##// END OF EJS Templates
Minor changes
paul -
r94:399cb300a264 VHDLib206
parent child
Show More
@@ -0,0 +1,9
1 #!/usr/bin/lppmon -e
2
3 proxy.loadSysDriver("AHBUARTplugin","AHBUART");
4 proxy.loadSysDriverToParent("dsu3plugin","AHBUART");
5 proxy.loadSysDriverToParent("APB UART PLUGIN","AHBUART");
6 AHBUART.open("/dev/ttyUSB0",30000000)
7 dsu3plugin0.openFile("/opt/DEV_PLE/FSW-qt/bin/fsw-vhdl-dev")
8 dsu3plugin0.loadFile()
9 dsu3plugin0.run()
@@ -0,0 +1,13
1 #!/usr/bin/lppmon -e
2
3 proxy.loadSysDriver("RMAPPlugin","RMAPplugin0");
4 proxy.loadSysDriverToParent("dsu3plugin","RMAPplugin0");
5
6 #BUTTON_selectStarDundee.click()
7 BUTTON_selectGRESB.click()
8
9 BUTTON_rmapOpenCommunication.click()
10 dsu3plugin0.openFile("/opt/DEV_PLE/FSW-qt/bin/fsw-vhdl-dev")
11 dsu3plugin0.loadFile()
12 dsu3plugin0.run()
13
@@ -0,0 +1,6
1 #!/usr/bin/lppmon -e
2
3 dsu3plugin0.openFile("/opt/DEV_PLE/FSW-qt/bin/fsw-vhdl-dev")
4 dsu3plugin0.loadFile()
5 dsu3plugin0.run()
6
@@ -1,39 +1,40
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
8 8 #include "fsw_params.h"
9 9 #include "fsw_spacewire.h"
10 10
11 11 rtems_name name_hk_rate_monotonic; // name of the HK rate monotonic
12 12 rtems_id HK_id; // id of the HK rate monotonic period
13 13
14 14 //extern rtems_name misc_name[5];
15 15 //time_management_regs_t *time_management_regs;
16 16 //extern Packet_TM_LFR_HK_t housekeeping_packet;
17 17
18 18 void configure_timer(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider,
19 19 unsigned char interrupt_level, rtems_isr (*timer_isr)() );
20 20 void timer_start( gptimer_regs_t *gptimer_regs, unsigned char timer );
21 21 void timer_stop( gptimer_regs_t *gptimer_regs, unsigned char timer );
22 22 void timer_set_clock_divider(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider);
23 23
24 24 // SERIAL LINK
25 25 int send_console_outputs_on_apbuart_port( void );
26 int enable_apbuart_transmitter( void );
26 27 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value);
27 28
28 29 // RTEMS TASKS
29 30 rtems_task stat_task( rtems_task_argument argument );
30 31 rtems_task hous_task( rtems_task_argument argument );
31 32 rtems_task dumb_task( rtems_task_argument unused );
32 33
33 34 void init_housekeeping_parameters( void );
34 35
35 36 void increment_seq_counter( unsigned char *packet_sequence_control);
36 37
37 38 void getTime( unsigned char *time);
38 39
39 40 #endif // FSW_MISC_H_INCLUDED
@@ -1,218 +1,222
1 1 #ifndef FSW_PARAMS_H_INCLUDED
2 2 #define FSW_PARAMS_H_INCLUDED
3 3
4 4 #include "grlib_regs.h"
5 5 #include "fsw_params_processing.h"
6 6 #include "tm_byte_positions.h"
7 7 #include "ccsds_types.h"
8 8
9 9 #define GRSPW_DEVICE_NAME "/dev/grspw0"
10 10 #define UART_DEVICE_NAME "/dev/console"
11 11
12 12 typedef struct ring_node
13 13 {
14 14 struct ring_node *previous;
15 15 int buffer_address;
16 16 struct ring_node *next;
17 17 unsigned int status;
18 18 } ring_node;
19 19
20 20 //************************
21 21 // flight software version
22 22 // this parameters is handled by the Qt project options
23 23
24 24 //#define NB_SAMPLES_PER_SNAPSHOT 2048
25 25 #define NB_SAMPLES_PER_SNAPSHOT 2352 // 336 * 7 = 2352
26 26 #define TIME_OFFSET 2
27 27 #define TIME_OFFSET_IN_BYTES 8
28 28 #define WAVEFORM_EXTENDED_HEADER_OFFSET 22
29 29 #define NB_BYTES_SWF_BLK (2 * 6)
30 30 #define NB_WORDS_SWF_BLK 3
31 31 #define NB_BYTES_CWF3_LIGHT_BLK 6
32 32 #define WFRM_INDEX_OF_LAST_PACKET 6 // waveforms are transmitted in groups of 2048 blocks, 6 packets of 340 and 1 of 8
33 33 #define NB_RING_NODES_F0 3 // AT LEAST 3
34 34 #define NB_RING_NODES_F1 5 // AT LEAST 3
35 35 #define NB_RING_NODES_F2 5 // AT LEAST 3
36 36 #define NB_RING_NODES_ASM_F0 8 // AT LEAST 3
37 37 #define NB_RING_NODES_ASM_F1 2 // AT LEAST 3
38 38 #define NB_RING_NODES_ASM_F2 2 // AT LEAST 3
39 39
40 40 //**********
41 41 // LFR MODES
42 42 #define LFR_MODE_STANDBY 0
43 43 #define LFR_MODE_NORMAL 1
44 44 #define LFR_MODE_BURST 2
45 45 #define LFR_MODE_SBM1 3
46 46 #define LFR_MODE_SBM2 4
47 47 #define LFR_MODE_NORMAL_CWF_F3 5
48 48
49 49 #define RTEMS_EVENT_MODE_STANDBY RTEMS_EVENT_0
50 50 #define RTEMS_EVENT_MODE_NORMAL RTEMS_EVENT_1
51 51 #define RTEMS_EVENT_MODE_BURST RTEMS_EVENT_2
52 52 #define RTEMS_EVENT_MODE_SBM1 RTEMS_EVENT_3
53 53 #define RTEMS_EVENT_MODE_SBM2 RTEMS_EVENT_4
54 54 #define RTEMS_EVENT_MODE_SBM2_WFRM RTEMS_EVENT_5
55 #define RTEMS_EVENT_MODE_NORMAL_SWF_F0 RTEMS_EVENT_6
56 #define RTEMS_EVENT_MODE_NORMAL_SWF_F1 RTEMS_EVENT_7
57 #define RTEMS_EVENT_MODE_NORMAL_SWF_F2 RTEMS_EVENT_8
55 58
56 59 //****************************
57 60 // LFR DEFAULT MODE PARAMETERS
58 61 // COMMON
59 62 #define DEFAULT_SY_LFR_COMMON0 0x00
60 63 #define DEFAULT_SY_LFR_COMMON1 0x10 // default value 0 0 0 1 0 0 0 0
61 64 // NORM
62 65 #define SY_LFR_N_SWF_L 2048 // nb sample
63 66 #define SY_LFR_N_SWF_P 20 // sec
64 67 #define SY_LFR_N_ASM_P 3600 // sec
65 68 #define SY_LFR_N_BP_P0 4 // sec
66 69 #define SY_LFR_N_BP_P1 20 // sec
67 70 #define MIN_DELTA_SNAPSHOT 16 // sec
68 71 // BURST
69 72 #define DEFAULT_SY_LFR_B_BP_P0 1 // sec
70 73 #define DEFAULT_SY_LFR_B_BP_P1 5 // sec
71 74 // SBM1
72 75 #define DEFAULT_SY_LFR_S1_BP_P0 1 // sec
73 76 #define DEFAULT_SY_LFR_S1_BP_P1 1 // sec
74 77 // SBM2
75 78 #define DEFAULT_SY_LFR_S2_BP_P0 1 // sec
76 79 #define DEFAULT_SY_LFR_S2_BP_P1 5 // sec
77 80 // ADDITIONAL PARAMETERS
78 81 #define TIME_BETWEEN_TWO_SWF_PACKETS 30 // nb x 10 ms => 300 ms
79 82 #define TIME_BETWEEN_TWO_CWF3_PACKETS 1000 // nb x 10 ms => 10 s
80 83 // STATUS WORD
81 84 #define DEFAULT_STATUS_WORD_BYTE0 0x0d // [0000] [1] [101] mode 4 bits / SPW enabled 1 bit / state is run 3 bits
82 85 #define DEFAULT_STATUS_WORD_BYTE1 0x00
83 86 //
84 87 #define SY_LFR_DPU_CONNECT_TIMEOUT 100 // 100 * 10 ms = 1 s
85 88 #define SY_LFR_DPU_CONNECT_ATTEMPT 3
86 89 //****************************
87 90
88 91 //*****************************
89 92 // APB REGISTERS BASE ADDRESSES
90 93 #define REGS_ADDR_APBUART 0x80000100
91 94 #define REGS_ADDR_GPTIMER 0x80000300
92 95 #define REGS_ADDR_GRSPW 0x80000500
93 96 #define REGS_ADDR_TIME_MANAGEMENT 0x80000600
94 97 #define REGS_ADDR_SPECTRAL_MATRIX 0x80000f00
95 98
96 99 #ifdef GSA
97 100 #else
98 101 #define REGS_ADDR_WAVEFORM_PICKER 0x80000f20
99 102 #endif
100 103
101 104 #define APBUART_CTRL_REG_MASK_DB 0xfffff7ff
105 #define APBUART_CTRL_REG_MASK_TE 0x00000002
102 106 #define APBUART_SCALER_RELOAD_VALUE 0x00000050 // 25 MHz => about 38400 (0x50)
103 107
104 108 //**********
105 109 // IRQ LINES
106 110 #define IRQ_SM 9
107 111 #define IRQ_SPARC_SM 0x19 // see sparcv8.pdf p.76 for interrupt levels
108 112 #define IRQ_WF 10
109 113 #define IRQ_SPARC_WF 0x1a // see sparcv8.pdf p.76 for interrupt levels
110 114 #define IRQ_TIME1 12
111 115 #define IRQ_SPARC_TIME1 0x1c // see sparcv8.pdf p.76 for interrupt levels
112 116 #define IRQ_TIME2 13
113 117 #define IRQ_SPARC_TIME2 0x1d // see sparcv8.pdf p.76 for interrupt levels
114 118 #define IRQ_WAVEFORM_PICKER 14
115 119 #define IRQ_SPARC_WAVEFORM_PICKER 0x1e // see sparcv8.pdf p.76 for interrupt levels
116 120 #define IRQ_SPECTRAL_MATRIX 6
117 121 #define IRQ_SPARC_SPECTRAL_MATRIX 0x16 // see sparcv8.pdf p.76 for interrupt levels
118 122
119 123 //*****
120 124 // TIME
121 125 #define CLKDIV_SM_SIMULATOR (10000 - 1) // 10 ms
122 126 #define CLKDIV_WF_SIMULATOR (10000000 - 1) // 10 000 000 * 1 us = 10 s
123 127 #define TIMER_SM_SIMULATOR 1
124 128 #define TIMER_WF_SIMULATOR 2
125 129 #define HK_PERIOD 100 // 100 * 10ms => 1sec
126 130
127 131 //**********
128 132 // LPP CODES
129 133 #define LFR_SUCCESSFUL 0
130 134 #define LFR_DEFAULT 1
131 135
132 136 //******
133 137 // RTEMS
134 138 #define TASKID_RECV 1
135 139 #define TASKID_ACTN 2
136 140 #define TASKID_SPIQ 3
137 141 #define TASKID_SMIQ 4
138 142 #define TASKID_STAT 5
139 143 #define TASKID_AVF0 6
140 144 #define TASKID_BPF0 7
141 145 #define TASKID_WFRM 8
142 146 #define TASKID_DUMB 9
143 147 #define TASKID_HOUS 10
144 148 #define TASKID_MATR 11
145 149 #define TASKID_CWF3 12
146 150 #define TASKID_CWF2 13
147 151 #define TASKID_CWF1 14
148 152 #define TASKID_SEND 15
149 153 #define TASKID_WTDG 16
150 154
151 155 #define TASK_PRIORITY_SPIQ 5
152 156 #define TASK_PRIORITY_SMIQ 10
153 157 #define TASK_PRIORITY_WTDG 20
154 158 #define TASK_PRIORITY_HOUS 30
155 159 #define TASK_PRIORITY_CWF1 35 // CWF1 and CWF2 are never running together
156 160 #define TASK_PRIORITY_CWF2 35 //
157 161 #define TASK_PRIORITY_WFRM 40
158 162 #define TASK_PRIORITY_CWF3 40 // there is a printf in this function, be careful with its priority wrt CWF1
159 163 #define TASK_PRIORITY_SEND 45
160 164 #define TASK_PRIORITY_RECV 50
161 165 #define TASK_PRIORITY_ACTN 50
162 166 #define TASK_PRIORITY_AVF0 60
163 167 #define TASK_PRIORITY_BPF0 60
164 168 #define TASK_PRIORITY_MATR 100
165 169 #define TASK_PRIORITY_STAT 200
166 170 #define TASK_PRIORITY_DUMB 200
167 171
168 172 #define ACTION_MSG_QUEUE_COUNT 10
169 173 #define ACTION_MSG_PKTS_COUNT 50
170 174 #define ACTION_MSG_PKTS_MAX_SIZE (PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES)
171 175 #define ACTION_MSG_SPW_IOCTL_SEND_SIZE 24 // hlen *hdr dlen *data sent options
172 176
173 177 #define QUEUE_RECV 0
174 178 #define QUEUE_SEND 1
175 179
176 180 //*******
177 181 // MACROS
178 182 #ifdef PRINT_MESSAGES_ON_CONSOLE
179 183 #define PRINTF(x) printf(x);
180 184 #define PRINTF1(x,y) printf(x,y);
181 185 #define PRINTF2(x,y,z) printf(x,y,z);
182 186 #else
183 187 #define PRINTF(x) ;
184 188 #define PRINTF1(x,y) ;
185 189 #define PRINTF2(x,y,z) ;
186 190 #endif
187 191
188 192 #ifdef BOOT_MESSAGES
189 193 #define BOOT_PRINTF(x) printf(x);
190 194 #define BOOT_PRINTF1(x,y) printf(x,y);
191 195 #define BOOT_PRINTF2(x,y,z) printf(x,y,z);
192 196 #else
193 197 #define BOOT_PRINTF(x) ;
194 198 #define BOOT_PRINTF1(x,y) ;
195 199 #define BOOT_PRINTF2(x,y,z) ;
196 200 #endif
197 201
198 202 #ifdef DEBUG_MESSAGES
199 203 #define DEBUG_PRINTF(x) printf(x);
200 204 #define DEBUG_PRINTF1(x,y) printf(x,y);
201 205 #define DEBUG_PRINTF2(x,y,z) printf(x,y,z);
202 206 #else
203 207 #define DEBUG_PRINTF(x) ;
204 208 #define DEBUG_PRINTF1(x,y) ;
205 209 #define DEBUG_PRINTF2(x,y,z) ;
206 210 #endif
207 211
208 212 #define CPU_USAGE_REPORT_PERIOD 6 // * 10 s = period
209 213
210 214 struct param_local_str{
211 215 unsigned int local_sbm1_nb_cwf_sent;
212 216 unsigned int local_sbm1_nb_cwf_max;
213 217 unsigned int local_sbm2_nb_cwf_sent;
214 218 unsigned int local_sbm2_nb_cwf_max;
215 219 unsigned int local_nb_interrupt_f0_MAX;
216 220 };
217 221
218 222 #endif // FSW_PARAMS_H_INCLUDED
@@ -1,607 +1,609
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_MAXIMUM_DRIVERS 16
36 36 #define CONFIGURE_MAXIMUM_PERIODS 5
37 37 #define CONFIGURE_MAXIMUM_TIMERS 5 // STAT (1s), send SWF (0.3s), send CWF3 (1s)
38 38 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 2
39 39 #ifdef PRINT_STACK_REPORT
40 40 #define CONFIGURE_STACK_CHECKER_ENABLED
41 41 #endif
42 42
43 43 #include <rtems/confdefs.h>
44 44
45 45 /* If --drvmgr was enabled during the configuration of the RTEMS kernel */
46 46 #ifdef RTEMS_DRVMGR_STARTUP
47 47 #ifdef LEON3
48 48 /* Add Timer and UART Driver */
49 49 #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
50 50 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GPTIMER
51 51 #endif
52 52 #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
53 53 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_APBUART
54 54 #endif
55 55 #endif
56 56 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GRSPW /* GRSPW Driver */
57 57 #include <drvmgr/drvmgr_confdefs.h>
58 58 #endif
59 59
60 60 #include "fsw_init.h"
61 61 #include "fsw_config.c"
62 62
63 63 rtems_task Init( rtems_task_argument ignored )
64 64 {
65 65 /** This is the RTEMS INIT taks, it the first task launched by the system.
66 66 *
67 67 * @param unused is the starting argument of the RTEMS task
68 68 *
69 69 * The INIT task create and run all other RTEMS tasks.
70 70 *
71 71 */
72 72
73 73
74 74 rtems_status_code status;
75 75 rtems_status_code status_spw;
76 76 rtems_isr_entry old_isr_handler;
77 77
78 78 // UART settings
79 set_apbuart_scaler_reload_register(REGS_ADDR_APBUART, APBUART_SCALER_RELOAD_VALUE);
79 80 send_console_outputs_on_apbuart_port();
80 set_apbuart_scaler_reload_register(REGS_ADDR_APBUART, APBUART_SCALER_RELOAD_VALUE);
81 enable_apbuart_transmitter();
82 PRINTF("\n\n\n\n\nIn INIT *** Now the console is on port COM1\n")
81 83
82 84 BOOT_PRINTF("\n\n\n\n\n")
83 85 BOOT_PRINTF("***************************\n")
84 86 BOOT_PRINTF("** START Flight Software **\n")
85 87 #ifdef VHDL_DEV
86 88 PRINTF("/!\\ this is the VHDL_DEV flight software /!\\ \n")
87 89 #endif
88 90 BOOT_PRINTF("***************************\n")
89 91 BOOT_PRINTF("\n\n")
90 92
91 93 reset_wfp_burst_enable(); // stop the waveform picker if it was running
92 94 init_waveform_rings(); // initialize the waveform rings
93 95
94 96 init_parameter_dump();
95 97 init_local_mode_parameters();
96 98 init_housekeeping_parameters();
97 99
98 100 updateLFRCurrentMode();
99 101
100 102 BOOT_PRINTF1("in INIT *** lfrCurrentMode is %d\n", lfrCurrentMode)
101 103
102 104 create_names(); // create all names
103 105
104 106 status = create_message_queues(); // create message queues
105 107 if (status != RTEMS_SUCCESSFUL)
106 108 {
107 109 PRINTF1("in INIT *** ERR in create_message_queues, code %d", status)
108 110 }
109 111
110 112 status = create_all_tasks(); // create all tasks
111 113 if (status != RTEMS_SUCCESSFUL)
112 114 {
113 115 PRINTF1("in INIT *** ERR in create_all_tasks, code %d", status)
114 116 }
115 117
116 118 // **************************
117 119 // <SPACEWIRE INITIALIZATION>
118 120 grspw_timecode_callback = &timecode_irq_handler;
119 121
120 122 status_spw = spacewire_open_link(); // (1) open the link
121 123 if ( status_spw != RTEMS_SUCCESSFUL )
122 124 {
123 125 PRINTF1("in INIT *** ERR spacewire_open_link code %d\n", status_spw )
124 126 }
125 127
126 128 if ( status_spw == RTEMS_SUCCESSFUL ) // (2) configure the link
127 129 {
128 130 status_spw = spacewire_configure_link( fdSPW );
129 131 if ( status_spw != RTEMS_SUCCESSFUL )
130 132 {
131 133 PRINTF1("in INIT *** ERR spacewire_configure_link code %d\n", status_spw )
132 134 }
133 135 }
134 136
135 137 if ( status_spw == RTEMS_SUCCESSFUL) // (3) start the link
136 138 {
137 139 status_spw = spacewire_start_link( fdSPW );
138 140 if ( status_spw != RTEMS_SUCCESSFUL )
139 141 {
140 142 PRINTF1("in INIT *** ERR spacewire_start_link code %d\n", status_spw )
141 143 }
142 144 }
143 145 // </SPACEWIRE INITIALIZATION>
144 146 // ***************************
145 147
146 148 status = start_all_tasks(); // start all tasks
147 149 if (status != RTEMS_SUCCESSFUL)
148 150 {
149 151 PRINTF1("in INIT *** ERR in start_all_tasks, code %d", status)
150 152 }
151 153
152 154 // start RECV and SEND *AFTER* SpaceWire Initialization, due to the timeout of the start call during the initialization
153 155 status = start_recv_send_tasks();
154 156 if ( status != RTEMS_SUCCESSFUL )
155 157 {
156 158 PRINTF1("in INIT *** ERR start_recv_send_tasks code %d\n", status )
157 159 }
158 160
159 161 // suspend science tasks. they will be restarted later depending on the mode
160 162 status = suspend_science_tasks(); // suspend science tasks (not done in stop_current_mode if current mode = STANDBY)
161 163 if (status != RTEMS_SUCCESSFUL)
162 164 {
163 165 PRINTF1("in INIT *** in suspend_science_tasks *** ERR code: %d\n", status)
164 166 }
165 167
166 168
167 169 //******************************
168 170 // <SPECTRAL MATRICES SIMULATOR>
169 171 LEON_Mask_interrupt( IRQ_SM );
170 172 configure_timer((gptimer_regs_t*) REGS_ADDR_GPTIMER, TIMER_SM_SIMULATOR, CLKDIV_SM_SIMULATOR,
171 173 IRQ_SPARC_SM, spectral_matrices_isr_simu );
172 174 // </SPECTRAL MATRICES SIMULATOR>
173 175 //*******************************
174 176
175 177 // configure IRQ handling for the waveform picker unit
176 178 status = rtems_interrupt_catch( waveforms_isr,
177 179 IRQ_SPARC_WAVEFORM_PICKER,
178 180 &old_isr_handler) ;
179 181
180 182 // if the spacewire link is not up then send an event to the SPIQ task for link recovery
181 183 if ( status_spw != RTEMS_SUCCESSFUL )
182 184 {
183 185 status = rtems_event_send( Task_id[TASKID_SPIQ], SPW_LINKERR_EVENT );
184 186 if ( status != RTEMS_SUCCESSFUL ) {
185 187 PRINTF1("in INIT *** ERR rtems_event_send to SPIQ code %d\n", status )
186 188 }
187 189 }
188 190
189 191 BOOT_PRINTF("delete INIT\n")
190 192
191 193 status = rtems_task_delete(RTEMS_SELF);
192 194
193 195 }
194 196
195 197 void init_local_mode_parameters( void )
196 198 {
197 199 /** This function initialize the param_local global variable with default values.
198 200 *
199 201 */
200 202
201 203 unsigned int i;
202 204
203 205 // LOCAL PARAMETERS
204 206 set_local_nb_interrupt_f0_MAX();
205 207
206 208 BOOT_PRINTF1("local_sbm1_nb_cwf_max %d \n", param_local.local_sbm1_nb_cwf_max)
207 209 BOOT_PRINTF1("local_sbm2_nb_cwf_max %d \n", param_local.local_sbm2_nb_cwf_max)
208 210 BOOT_PRINTF1("nb_interrupt_f0_MAX = %d\n", param_local.local_nb_interrupt_f0_MAX)
209 211
210 212 // init sequence counters
211 213
212 214 for(i = 0; i<SEQ_CNT_NB_DEST_ID; i++)
213 215 {
214 216 sequenceCounters_TC_EXE[i] = 0x00;
215 217 }
216 218 sequenceCounters_SCIENCE_NORMAL_BURST = 0x00;
217 219 sequenceCounters_SCIENCE_SBM1_SBM2 = 0x00;
218 220 }
219 221
220 222 void create_names( void ) // create all names for tasks and queues
221 223 {
222 224 /** This function creates all RTEMS names used in the software for tasks and queues.
223 225 *
224 226 * @return RTEMS directive status codes:
225 227 * - RTEMS_SUCCESSFUL - successful completion
226 228 *
227 229 */
228 230
229 231 // task names
230 232 Task_name[TASKID_RECV] = rtems_build_name( 'R', 'E', 'C', 'V' );
231 233 Task_name[TASKID_ACTN] = rtems_build_name( 'A', 'C', 'T', 'N' );
232 234 Task_name[TASKID_SPIQ] = rtems_build_name( 'S', 'P', 'I', 'Q' );
233 235 Task_name[TASKID_SMIQ] = rtems_build_name( 'S', 'M', 'I', 'Q' );
234 236 Task_name[TASKID_STAT] = rtems_build_name( 'S', 'T', 'A', 'T' );
235 237 Task_name[TASKID_AVF0] = rtems_build_name( 'A', 'V', 'F', '0' );
236 238 Task_name[TASKID_BPF0] = rtems_build_name( 'B', 'P', 'F', '0' );
237 239 Task_name[TASKID_WFRM] = rtems_build_name( 'W', 'F', 'R', 'M' );
238 240 Task_name[TASKID_DUMB] = rtems_build_name( 'D', 'U', 'M', 'B' );
239 241 Task_name[TASKID_HOUS] = rtems_build_name( 'H', 'O', 'U', 'S' );
240 242 Task_name[TASKID_MATR] = rtems_build_name( 'M', 'A', 'T', 'R' );
241 243 Task_name[TASKID_CWF3] = rtems_build_name( 'C', 'W', 'F', '3' );
242 244 Task_name[TASKID_CWF2] = rtems_build_name( 'C', 'W', 'F', '2' );
243 245 Task_name[TASKID_CWF1] = rtems_build_name( 'C', 'W', 'F', '1' );
244 246 Task_name[TASKID_SEND] = rtems_build_name( 'S', 'E', 'N', 'D' );
245 247 Task_name[TASKID_WTDG] = rtems_build_name( 'W', 'T', 'D', 'G' );
246 248
247 249 // rate monotonic period names
248 250 name_hk_rate_monotonic = rtems_build_name( 'H', 'O', 'U', 'S' );
249 251
250 252 misc_name[QUEUE_RECV] = rtems_build_name( 'Q', '_', 'R', 'V' );
251 253 misc_name[QUEUE_SEND] = rtems_build_name( 'Q', '_', 'S', 'D' );
252 254 }
253 255
254 256 int create_all_tasks( void ) // create all tasks which run in the software
255 257 {
256 258 /** This function creates all RTEMS tasks used in the software.
257 259 *
258 260 * @return RTEMS directive status codes:
259 261 * - RTEMS_SUCCESSFUL - task created successfully
260 262 * - RTEMS_INVALID_ADDRESS - id is NULL
261 263 * - RTEMS_INVALID_NAME - invalid task name
262 264 * - RTEMS_INVALID_PRIORITY - invalid task priority
263 265 * - RTEMS_MP_NOT_CONFIGURED - multiprocessing not configured
264 266 * - RTEMS_TOO_MANY - too many tasks created
265 267 * - RTEMS_UNSATISFIED - not enough memory for stack/FP context
266 268 * - RTEMS_TOO_MANY - too many global objects
267 269 *
268 270 */
269 271
270 272 rtems_status_code status;
271 273
272 274 // RECV
273 275 status = rtems_task_create(
274 276 Task_name[TASKID_RECV], TASK_PRIORITY_RECV, RTEMS_MINIMUM_STACK_SIZE,
275 277 RTEMS_DEFAULT_MODES,
276 278 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_RECV]
277 279 );
278 280
279 281 if (status == RTEMS_SUCCESSFUL) // ACTN
280 282 {
281 283 status = rtems_task_create(
282 284 Task_name[TASKID_ACTN], TASK_PRIORITY_ACTN, RTEMS_MINIMUM_STACK_SIZE,
283 285 RTEMS_DEFAULT_MODES,
284 286 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_ACTN]
285 287 );
286 288 }
287 289 if (status == RTEMS_SUCCESSFUL) // SPIQ
288 290 {
289 291 status = rtems_task_create(
290 292 Task_name[TASKID_SPIQ], TASK_PRIORITY_SPIQ, RTEMS_MINIMUM_STACK_SIZE,
291 293 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
292 294 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SPIQ]
293 295 );
294 296 }
295 297 if (status == RTEMS_SUCCESSFUL) // SMIQ
296 298 {
297 299 status = rtems_task_create(
298 300 Task_name[TASKID_SMIQ], TASK_PRIORITY_SMIQ, RTEMS_MINIMUM_STACK_SIZE,
299 301 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
300 302 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SMIQ]
301 303 );
302 304 }
303 305 if (status == RTEMS_SUCCESSFUL) // STAT
304 306 {
305 307 status = rtems_task_create(
306 308 Task_name[TASKID_STAT], TASK_PRIORITY_STAT, RTEMS_MINIMUM_STACK_SIZE,
307 309 RTEMS_DEFAULT_MODES,
308 310 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_STAT]
309 311 );
310 312 }
311 313 if (status == RTEMS_SUCCESSFUL) // AVF0
312 314 {
313 315 status = rtems_task_create(
314 316 Task_name[TASKID_AVF0], TASK_PRIORITY_AVF0, RTEMS_MINIMUM_STACK_SIZE,
315 317 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
316 318 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF0]
317 319 );
318 320 }
319 321 if (status == RTEMS_SUCCESSFUL) // BPF0
320 322 {
321 323 status = rtems_task_create(
322 324 Task_name[TASKID_BPF0], TASK_PRIORITY_BPF0, RTEMS_MINIMUM_STACK_SIZE,
323 325 RTEMS_DEFAULT_MODES,
324 326 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_BPF0]
325 327 );
326 328 }
327 329 if (status == RTEMS_SUCCESSFUL) // WFRM
328 330 {
329 331 status = rtems_task_create(
330 332 Task_name[TASKID_WFRM], TASK_PRIORITY_WFRM, RTEMS_MINIMUM_STACK_SIZE,
331 333 RTEMS_DEFAULT_MODES,
332 334 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_WFRM]
333 335 );
334 336 }
335 337 if (status == RTEMS_SUCCESSFUL) // DUMB
336 338 {
337 339 status = rtems_task_create(
338 340 Task_name[TASKID_DUMB], TASK_PRIORITY_DUMB, RTEMS_MINIMUM_STACK_SIZE,
339 341 RTEMS_DEFAULT_MODES,
340 342 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_DUMB]
341 343 );
342 344 }
343 345 if (status == RTEMS_SUCCESSFUL) // HOUS
344 346 {
345 347 status = rtems_task_create(
346 348 Task_name[TASKID_HOUS], TASK_PRIORITY_HOUS, RTEMS_MINIMUM_STACK_SIZE,
347 349 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
348 350 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_HOUS]
349 351 );
350 352 }
351 353 if (status == RTEMS_SUCCESSFUL) // MATR
352 354 {
353 355 status = rtems_task_create(
354 356 Task_name[TASKID_MATR], TASK_PRIORITY_MATR, RTEMS_MINIMUM_STACK_SIZE,
355 357 RTEMS_DEFAULT_MODES,
356 358 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_MATR]
357 359 );
358 360 }
359 361 if (status == RTEMS_SUCCESSFUL) // CWF3
360 362 {
361 363 status = rtems_task_create(
362 364 Task_name[TASKID_CWF3], TASK_PRIORITY_CWF3, RTEMS_MINIMUM_STACK_SIZE,
363 365 RTEMS_DEFAULT_MODES,
364 366 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_CWF3]
365 367 );
366 368 }
367 369 if (status == RTEMS_SUCCESSFUL) // CWF2
368 370 {
369 371 status = rtems_task_create(
370 372 Task_name[TASKID_CWF2], TASK_PRIORITY_CWF2, RTEMS_MINIMUM_STACK_SIZE,
371 373 RTEMS_DEFAULT_MODES,
372 374 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_CWF2]
373 375 );
374 376 }
375 377 if (status == RTEMS_SUCCESSFUL) // CWF1
376 378 {
377 379 status = rtems_task_create(
378 380 Task_name[TASKID_CWF1], TASK_PRIORITY_CWF1, RTEMS_MINIMUM_STACK_SIZE,
379 381 RTEMS_DEFAULT_MODES,
380 382 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_CWF1]
381 383 );
382 384 }
383 385 if (status == RTEMS_SUCCESSFUL) // SEND
384 386 {
385 387 status = rtems_task_create(
386 388 Task_name[TASKID_SEND], TASK_PRIORITY_SEND, RTEMS_MINIMUM_STACK_SIZE,
387 389 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
388 390 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SEND]
389 391 );
390 392 }
391 393 if (status == RTEMS_SUCCESSFUL) // WTDG
392 394 {
393 395 status = rtems_task_create(
394 396 Task_name[TASKID_WTDG], TASK_PRIORITY_WTDG, RTEMS_MINIMUM_STACK_SIZE,
395 397 RTEMS_DEFAULT_MODES,
396 398 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_WTDG]
397 399 );
398 400 }
399 401
400 402 return status;
401 403 }
402 404
403 405 int start_recv_send_tasks( void )
404 406 {
405 407 rtems_status_code status;
406 408
407 409 status = rtems_task_start( Task_id[TASKID_RECV], recv_task, 1 );
408 410 if (status!=RTEMS_SUCCESSFUL) {
409 411 BOOT_PRINTF("in INIT *** Error starting TASK_RECV\n")
410 412 }
411 413
412 414 if (status == RTEMS_SUCCESSFUL) // SEND
413 415 {
414 416 status = rtems_task_start( Task_id[TASKID_SEND], send_task, 1 );
415 417 if (status!=RTEMS_SUCCESSFUL) {
416 418 BOOT_PRINTF("in INIT *** Error starting TASK_SEND\n")
417 419 }
418 420 }
419 421
420 422 return status;
421 423 }
422 424
423 425 int start_all_tasks( void ) // start all tasks except SEND RECV and HOUS
424 426 {
425 427 /** This function starts all RTEMS tasks used in the software.
426 428 *
427 429 * @return RTEMS directive status codes:
428 430 * - RTEMS_SUCCESSFUL - ask started successfully
429 431 * - RTEMS_INVALID_ADDRESS - invalid task entry point
430 432 * - RTEMS_INVALID_ID - invalid task id
431 433 * - RTEMS_INCORRECT_STATE - task not in the dormant state
432 434 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot start remote task
433 435 *
434 436 */
435 437 // starts all the tasks fot eh flight software
436 438
437 439 rtems_status_code status;
438 440
439 441 status = rtems_task_start( Task_id[TASKID_SPIQ], spiq_task, 1 );
440 442 if (status!=RTEMS_SUCCESSFUL) {
441 443 BOOT_PRINTF("in INIT *** Error starting TASK_SPIQ\n")
442 444 }
443 445
444 446 if (status == RTEMS_SUCCESSFUL) // WTDG
445 447 {
446 448 status = rtems_task_start( Task_id[TASKID_WTDG], wtdg_task, 1 );
447 449 if (status!=RTEMS_SUCCESSFUL) {
448 450 BOOT_PRINTF("in INIT *** Error starting TASK_WTDG\n")
449 451 }
450 452 }
451 453
452 454 if (status == RTEMS_SUCCESSFUL) // SMIQ
453 455 {
454 456 status = rtems_task_start( Task_id[TASKID_SMIQ], smiq_task, 1 );
455 457 if (status!=RTEMS_SUCCESSFUL) {
456 458 BOOT_PRINTF("in INIT *** Error starting TASK_BPPR\n")
457 459 }
458 460 }
459 461
460 462 if (status == RTEMS_SUCCESSFUL) // ACTN
461 463 {
462 464 status = rtems_task_start( Task_id[TASKID_ACTN], actn_task, 1 );
463 465 if (status!=RTEMS_SUCCESSFUL) {
464 466 BOOT_PRINTF("in INIT *** Error starting TASK_ACTN\n")
465 467 }
466 468 }
467 469
468 470 if (status == RTEMS_SUCCESSFUL) // STAT
469 471 {
470 472 status = rtems_task_start( Task_id[TASKID_STAT], stat_task, 1 );
471 473 if (status!=RTEMS_SUCCESSFUL) {
472 474 BOOT_PRINTF("in INIT *** Error starting TASK_STAT\n")
473 475 }
474 476 }
475 477
476 478 if (status == RTEMS_SUCCESSFUL) // AVF0
477 479 {
478 480 status = rtems_task_start( Task_id[TASKID_AVF0], avf0_task, 1 );
479 481 if (status!=RTEMS_SUCCESSFUL) {
480 482 BOOT_PRINTF("in INIT *** Error starting TASK_AVF0\n")
481 483 }
482 484 }
483 485
484 486 if (status == RTEMS_SUCCESSFUL) // BPF0
485 487 {
486 488 status = rtems_task_start( Task_id[TASKID_BPF0], bpf0_task, 1 );
487 489 if (status!=RTEMS_SUCCESSFUL) {
488 490 BOOT_PRINTF("in INIT *** Error starting TASK_BPF0\n")
489 491 }
490 492 }
491 493
492 494 if (status == RTEMS_SUCCESSFUL) // WFRM
493 495 {
494 496 status = rtems_task_start( Task_id[TASKID_WFRM], wfrm_task, 1 );
495 497 if (status!=RTEMS_SUCCESSFUL) {
496 498 BOOT_PRINTF("in INIT *** Error starting TASK_WFRM\n")
497 499 }
498 500 }
499 501
500 502 if (status == RTEMS_SUCCESSFUL) // DUMB
501 503 {
502 504 status = rtems_task_start( Task_id[TASKID_DUMB], dumb_task, 1 );
503 505 if (status!=RTEMS_SUCCESSFUL) {
504 506 BOOT_PRINTF("in INIT *** Error starting TASK_DUMB\n")
505 507 }
506 508 }
507 509
508 510 if (status == RTEMS_SUCCESSFUL) // HOUS
509 511 {
510 512 status = rtems_task_start( Task_id[TASKID_HOUS], hous_task, 1 );
511 513 if (status!=RTEMS_SUCCESSFUL) {
512 514 BOOT_PRINTF("in INIT *** Error starting TASK_HOUS\n")
513 515 }
514 516 }
515 517
516 518 if (status == RTEMS_SUCCESSFUL) // MATR
517 519 {
518 520 status = rtems_task_start( Task_id[TASKID_MATR], matr_task, 1 );
519 521 if (status!=RTEMS_SUCCESSFUL) {
520 522 BOOT_PRINTF("in INIT *** Error starting TASK_MATR\n")
521 523 }
522 524 }
523 525
524 526 if (status == RTEMS_SUCCESSFUL) // CWF3
525 527 {
526 528 status = rtems_task_start( Task_id[TASKID_CWF3], cwf3_task, 1 );
527 529 if (status!=RTEMS_SUCCESSFUL) {
528 530 BOOT_PRINTF("in INIT *** Error starting TASK_CWF3\n")
529 531 }
530 532 }
531 533
532 534 if (status == RTEMS_SUCCESSFUL) // CWF2
533 535 {
534 536 status = rtems_task_start( Task_id[TASKID_CWF2], cwf2_task, 1 );
535 537 if (status!=RTEMS_SUCCESSFUL) {
536 538 BOOT_PRINTF("in INIT *** Error starting TASK_CWF2\n")
537 539 }
538 540 }
539 541
540 542 if (status == RTEMS_SUCCESSFUL) // CWF1
541 543 {
542 544 status = rtems_task_start( Task_id[TASKID_CWF1], cwf1_task, 1 );
543 545 if (status!=RTEMS_SUCCESSFUL) {
544 546 BOOT_PRINTF("in INIT *** Error starting TASK_CWF1\n")
545 547 }
546 548 }
547 549 return status;
548 550 }
549 551
550 552 rtems_status_code create_message_queues( void ) // create the two message queues used in the software
551 553 {
552 554 rtems_status_code status_recv;
553 555 rtems_status_code status_send;
554 556 rtems_status_code ret;
555 557 rtems_id queue_id;
556 558
557 559 // create the queue for handling valid TCs
558 560 status_recv = rtems_message_queue_create( misc_name[QUEUE_RECV],
559 561 ACTION_MSG_QUEUE_COUNT, CCSDS_TC_PKT_MAX_SIZE,
560 562 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
561 563 if ( status_recv != RTEMS_SUCCESSFUL ) {
562 564 PRINTF1("in create_message_queues *** ERR creating QUEU queue, %d\n", status_recv)
563 565 }
564 566
565 567 // create the queue for handling TM packet sending
566 568 status_send = rtems_message_queue_create( misc_name[QUEUE_SEND],
567 569 ACTION_MSG_PKTS_COUNT, ACTION_MSG_PKTS_MAX_SIZE,
568 570 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
569 571 if ( status_send != RTEMS_SUCCESSFUL ) {
570 572 PRINTF1("in create_message_queues *** ERR creating PKTS queue, %d\n", status_send)
571 573 }
572 574
573 575 if ( status_recv != RTEMS_SUCCESSFUL )
574 576 {
575 577 ret = status_recv;
576 578 }
577 579 else
578 580 {
579 581 ret = status_send;
580 582 }
581 583
582 584 return ret;
583 585 }
584 586
585 587 rtems_status_code get_message_queue_id_send( rtems_id *queue_id )
586 588 {
587 589 rtems_status_code status;
588 590 rtems_name queue_name;
589 591
590 592 queue_name = rtems_build_name( 'Q', '_', 'S', 'D' );
591 593
592 594 status = rtems_message_queue_ident( queue_name, 0, queue_id );
593 595
594 596 return status;
595 597 }
596 598
597 599 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id )
598 600 {
599 601 rtems_status_code status;
600 602 rtems_name queue_name;
601 603
602 604 queue_name = rtems_build_name( 'Q', '_', 'R', 'V' );
603 605
604 606 status = rtems_message_queue_ident( queue_name, 0, queue_id );
605 607
606 608 return status;
607 609 }
@@ -1,341 +1,341
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 //char *DumbMessages[7] = {"in DUMB *** default", // RTEMS_EVENT_0
11 // "in DUMB *** timecode_irq_handler", // RTEMS_EVENT_1
12 // "in DUMB *** waveforms_isr", // RTEMS_EVENT_2
13 // "in DUMB *** in SMIQ *** Error sending event to AVF0", // RTEMS_EVENT_3
14 // "in DUMB *** spectral_matrices_isr *** Error sending event to SMIQ", // RTEMS_EVENT_4
15 // "in DUMB *** waveforms_simulator_isr", // RTEMS_EVENT_5
16 // "ERR HK" // RTEMS_EVENT_6
17 //};
18
19 10 void configure_timer(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider,
20 11 unsigned char interrupt_level, rtems_isr (*timer_isr)() )
21 12 {
22 13 /** This function configures a GPTIMER timer instantiated in the VHDL design.
23 14 *
24 15 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
25 16 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
26 17 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
27 18 * @param interrupt_level is the interrupt level that the timer drives.
28 19 * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer.
29 20 *
30 21 * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76
31 22 *
32 23 */
33 24
34 25 rtems_status_code status;
35 26 rtems_isr_entry old_isr_handler;
36 27
37 28 status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels
38 29 if (status!=RTEMS_SUCCESSFUL)
39 30 {
40 31 PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n")
41 32 }
42 33
43 34 timer_set_clock_divider( gptimer_regs, timer, clock_divider);
44 35 }
45 36
46 37 void timer_start(gptimer_regs_t *gptimer_regs, unsigned char timer)
47 38 {
48 39 /** This function starts a GPTIMER timer.
49 40 *
50 41 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
51 42 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
52 43 *
53 44 */
54 45
55 46 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
56 47 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000004; // LD load value from the reload register
57 48 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000001; // EN enable the timer
58 49 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000002; // RS restart
59 50 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000008; // IE interrupt enable
60 51 }
61 52
62 53 void timer_stop(gptimer_regs_t *gptimer_regs, unsigned char timer)
63 54 {
64 55 /** This function stops a GPTIMER timer.
65 56 *
66 57 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
67 58 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
68 59 *
69 60 */
70 61
71 62 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xfffffffe; // EN enable the timer
72 63 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xffffffef; // IE interrupt enable
73 64 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
74 65 }
75 66
76 67 void timer_set_clock_divider(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider)
77 68 {
78 69 /** This function sets the clock divider of a GPTIMER timer.
79 70 *
80 71 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
81 72 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
82 73 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
83 74 *
84 75 */
85 76
86 77 gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz
87 78 }
88 79
89 80 int send_console_outputs_on_apbuart_port( void ) // Send the console outputs on the apbuart port
90 81 {
91 82 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
92 83
93 84 apbuart_regs->ctrl = apbuart_regs->ctrl & APBUART_CTRL_REG_MASK_DB;
94 PRINTF("\n\n\n\n\nIn INIT *** Now the console is on port COM1\n")
85
86 return 0;
87 }
88
89 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
90 {
91 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
92
93 apbuart_regs->ctrl = apbuart_regs->ctrl | APBUART_CTRL_REG_MASK_TE;
95 94
96 95 return 0;
97 96 }
98 97
99 98 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
100 99 {
101 100 /** This function sets the scaler reload register of the apbuart module
102 101 *
103 102 * @param regs is the address of the apbuart registers in memory
104 103 * @param value is the value that will be stored in the scaler register
105 104 *
106 105 * The value shall be set by the software to get data on the serial interface.
107 106 *
108 107 */
109 108
110 109 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
111 110
112 111 apbuart_regs->scaler = value;
113 112 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
114 113 }
115 114
116 115 //************
117 116 // RTEMS TASKS
118 117
119 118 rtems_task stat_task(rtems_task_argument argument)
120 119 {
121 120 int i;
122 121 int j;
123 122 i = 0;
124 123 j = 0;
125 124 BOOT_PRINTF("in STAT *** \n")
126 125 while(1){
127 126 rtems_task_wake_after(1000);
128 127 PRINTF1("%d\n", j)
129 128 if (i == CPU_USAGE_REPORT_PERIOD) {
130 129 // #ifdef PRINT_TASK_STATISTICS
131 130 // rtems_cpu_usage_report();
132 131 // rtems_cpu_usage_reset();
133 132 // #endif
134 133 i = 0;
135 134 }
136 135 else i++;
137 136 j++;
138 137 }
139 138 }
140 139
141 140 rtems_task hous_task(rtems_task_argument argument)
142 141 {
143 142 rtems_status_code status;
144 143 rtems_id queue_id;
145 144
146 145 status = get_message_queue_id_send( &queue_id );
147 146 if (status != RTEMS_SUCCESSFUL)
148 147 {
149 148 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
150 149 }
151 150
152 151 BOOT_PRINTF("in HOUS ***\n")
153 152
154 153 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
155 154 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
156 155 if( status != RTEMS_SUCCESSFUL ) {
157 156 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status )
158 157 }
159 158 }
160 159
161 160 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
162 161 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
163 162 housekeeping_packet.reserved = DEFAULT_RESERVED;
164 163 housekeeping_packet.userApplication = CCSDS_USER_APP;
165 164 housekeeping_packet.packetID[0] = (unsigned char) (TM_PACKET_ID_HK >> 8);
166 165 housekeeping_packet.packetID[1] = (unsigned char) (TM_PACKET_ID_HK);
167 166 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
168 167 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
169 168 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
170 169 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
171 170 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
172 171 housekeeping_packet.serviceType = TM_TYPE_HK;
173 172 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
174 173 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
175 174 housekeeping_packet.sid = SID_HK;
176 175
177 176 status = rtems_rate_monotonic_cancel(HK_id);
178 177 if( status != RTEMS_SUCCESSFUL ) {
179 178 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status )
180 179 }
181 180 else {
182 181 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n")
183 182 }
184 183
185 184 while(1){ // launch the rate monotonic task
186 185 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
187 186 if ( status != RTEMS_SUCCESSFUL ) {
188 187 PRINTF1( "in HOUS *** ERR period: %d\n", status);
189 188 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
190 189 }
191 190 else {
192 191 increment_seq_counter( housekeeping_packet.packetSequenceControl );
193 192 housekeeping_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
194 193 housekeeping_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
195 194 housekeeping_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
196 195 housekeeping_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
197 196 housekeeping_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
198 197 housekeeping_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
199 198
200 199 spacewire_update_statistics();
201 200
202 201 // SEND PACKET
203 202 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
204 203 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
205 204 if (status != RTEMS_SUCCESSFUL) {
206 205 PRINTF1("in HOUS *** ERR send: %d\n", status)
207 206 }
208 207 }
209 208 }
210 209
211 210 PRINTF("in HOUS *** deleting task\n")
212 211
213 212 status = rtems_task_delete( RTEMS_SELF ); // should not return
214 213 printf( "rtems_task_delete returned with status of %d.\n", status );
215 214 return;
216 215 }
217 216
218 217 rtems_task dumb_task( rtems_task_argument unused )
219 218 {
220 219 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
221 220 *
222 221 * @param unused is the starting argument of the RTEMS task
223 222 *
224 223 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
225 224 *
226 225 */
227 226
228 227 unsigned int i;
229 228 unsigned int intEventOut;
230 229 unsigned int coarse_time = 0;
231 230 unsigned int fine_time = 0;
232 231 rtems_event_set event_out;
233 232
234 233 char *DumbMessages[8] = {"in DUMB *** default", // RTEMS_EVENT_0
235 234 "in DUMB *** timecode_irq_handler", // RTEMS_EVENT_1
236 235 "in DUMB *** waveforms_isr", // RTEMS_EVENT_2
237 236 "in DUMB *** in SMIQ *** Error sending event to AVF0", // RTEMS_EVENT_3
238 237 "in DUMB *** spectral_matrices_isr *** Error sending event to SMIQ", // RTEMS_EVENT_4
239 238 "in DUMB *** waveforms_simulator_isr", // RTEMS_EVENT_5
240 239 "ERR HK", // RTEMS_EVENT_6
241 240 "ready for dump" // RTEMS_EVENT_7
242 241 };
243 242
244 243 BOOT_PRINTF("in DUMB *** \n")
245 244
246 245 while(1){
247 246 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
248 247 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7,
249 248 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
250 249 intEventOut = (unsigned int) event_out;
251 250 for ( i=0; i<32; i++)
252 251 {
253 252 if ( ((intEventOut >> i) & 0x0001) != 0)
254 253 {
255 254 coarse_time = time_management_regs->coarse_time;
256 255 fine_time = time_management_regs->fine_time;
257 256 printf("in DUMB *** coarse: %x, fine: %x, %s\n", coarse_time, fine_time, DumbMessages[i]);
257 PRINTF1("status = %x\n", waveform_picker_regs->status)
258 258 }
259 259 }
260 260 }
261 261 }
262 262
263 263 //*****************************
264 264 // init housekeeping parameters
265 265
266 266 void init_housekeeping_parameters( void )
267 267 {
268 268 /** This function initialize the housekeeping_packet global variable with default values.
269 269 *
270 270 */
271 271
272 272 unsigned int i = 0;
273 273 unsigned char *parameters;
274 274
275 275 parameters = (unsigned char*) &housekeeping_packet.lfr_status_word;
276 276 for(i = 0; i< SIZE_HK_PARAMETERS; i++)
277 277 {
278 278 parameters[i] = 0x00;
279 279 }
280 280 // init status word
281 281 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
282 282 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
283 283 // init software version
284 284 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
285 285 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
286 286 housekeeping_packet.lfr_sw_version[2] = SW_VERSION_N3;
287 287 housekeeping_packet.lfr_sw_version[3] = SW_VERSION_N4;
288 288 // init fpga version
289 289 parameters = (unsigned char *) (REGS_ADDR_WAVEFORM_PICKER + 0xd0);
290 290 housekeeping_packet.lfr_fpga_version[0] = parameters[1]; // n1
291 291 housekeeping_packet.lfr_fpga_version[1] = parameters[2]; // n2
292 292 housekeeping_packet.lfr_fpga_version[2] = parameters[3]; // n3
293 293 }
294 294
295 295 void increment_seq_counter( unsigned char *packet_sequence_control)
296 296 {
297 297 /** This function increment the sequence counter psased in argument.
298 298 *
299 299 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
300 300 *
301 301 */
302 302
303 303 unsigned short sequence_cnt;
304 304 unsigned short segmentation_grouping_flag;
305 305 unsigned short new_packet_sequence_control;
306 306
307 307 segmentation_grouping_flag = (unsigned short) ( (packet_sequence_control[0] & 0xc0) << 8 ); // keep bits 7 downto 6
308 308 sequence_cnt = (unsigned short) (
309 309 ( (packet_sequence_control[0] & 0x3f) << 8 ) // keep bits 5 downto 0
310 310 + packet_sequence_control[1]
311 311 );
312 312
313 313 if ( sequence_cnt < SEQ_CNT_MAX)
314 314 {
315 315 sequence_cnt = sequence_cnt + 1;
316 316 }
317 317 else
318 318 {
319 319 sequence_cnt = 0;
320 320 }
321 321
322 322 new_packet_sequence_control = segmentation_grouping_flag | sequence_cnt ;
323 323
324 324 packet_sequence_control[0] = (unsigned char) (new_packet_sequence_control >> 8);
325 325 packet_sequence_control[1] = (unsigned char) (new_packet_sequence_control );
326 326 }
327 327
328 328 void getTime( unsigned char *time)
329 329 {
330 330 /** This function write the current local time in the time buffer passed in argument.
331 331 *
332 332 */
333 333
334 334 time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
335 335 time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
336 336 time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
337 337 time[3] = (unsigned char) (time_management_regs->coarse_time);
338 338 time[4] = (unsigned char) (time_management_regs->fine_time>>8);
339 339 time[5] = (unsigned char) (time_management_regs->fine_time);
340 340 }
341 341
@@ -1,1250 +1,1261
1 1 /** Functions and tasks related to waveform packet generation.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * A group of functions to handle waveforms, in snapshot or continuous format.\n
7 7 *
8 8 */
9 9
10 10 #include "wf_handler.h"
11 11
12 12 //*****************
13 13 // waveform headers
14 14 // SWF
15 15 Header_TM_LFR_SCIENCE_SWF_t headerSWF_F0[7];
16 16 Header_TM_LFR_SCIENCE_SWF_t headerSWF_F1[7];
17 17 Header_TM_LFR_SCIENCE_SWF_t headerSWF_F2[7];
18 18 // CWF
19 19 Header_TM_LFR_SCIENCE_CWF_t headerCWF_F1[7];
20 20 Header_TM_LFR_SCIENCE_CWF_t headerCWF_F2_BURST[7];
21 21 Header_TM_LFR_SCIENCE_CWF_t headerCWF_F2_SBM2[7];
22 22 Header_TM_LFR_SCIENCE_CWF_t headerCWF_F3[7];
23 23 Header_TM_LFR_SCIENCE_CWF_t headerCWF_F3_light[7];
24 24
25 25 //**************
26 26 // waveform ring
27 27 ring_node waveform_ring_f0[NB_RING_NODES_F0];
28 28 ring_node waveform_ring_f1[NB_RING_NODES_F1];
29 29 ring_node waveform_ring_f2[NB_RING_NODES_F2];
30 30 ring_node *current_ring_node_f0;
31 31 ring_node *ring_node_to_send_swf_f0;
32 32 ring_node *current_ring_node_f1;
33 33 ring_node *ring_node_to_send_swf_f1;
34 34 ring_node *ring_node_to_send_cwf_f1;
35 35 ring_node *current_ring_node_f2;
36 36 ring_node *ring_node_to_send_swf_f2;
37 37 ring_node *ring_node_to_send_cwf_f2;
38 38
39 39 rtems_isr waveforms_isr( rtems_vector_number vector )
40 40 {
41 41 /** This is the interrupt sub routine called by the waveform picker core.
42 42 *
43 43 * This ISR launch different actions depending mainly on two pieces of information:
44 44 * 1. the values read in the registers of the waveform picker.
45 45 * 2. the current LFR mode.
46 46 *
47 47 */
48 48
49 static unsigned char nb_swf = 0;
50
51 49 if ( (lfrCurrentMode == LFR_MODE_NORMAL)
52 50 || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) )
53 51 { // in modes other than STANDBY and BURST, send the CWF_F3 data
54 52 if ((waveform_picker_regs->status & 0x08) == 0x08){ // [1000] f3 is full
55 53 // (1) change the receiving buffer for the waveform picker
56 54 if (waveform_picker_regs->addr_data_f3 == (int) wf_cont_f3_a) {
57 55 waveform_picker_regs->addr_data_f3 = (int) (wf_cont_f3_b);
58 56 }
59 57 else {
60 58 waveform_picker_regs->addr_data_f3 = (int) (wf_cont_f3_a);
61 59 }
62 60 // (2) send an event for the waveforms transmission
63 61 if (rtems_event_send( Task_id[TASKID_CWF3], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
64 62 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 );
65 63 }
66 64 waveform_picker_regs->status = waveform_picker_regs->status & 0xfffff777; // reset f3 bits to 0, [1111 0111 0111 0111]
67 65 }
68 66 }
69 67
70 68 switch(lfrCurrentMode)
71 69 {
72 70 //********
73 71 // STANDBY
74 72 case(LFR_MODE_STANDBY):
75 73 break;
76 74
77 75 //******
78 76 // NORMAL
79 77 case(LFR_MODE_NORMAL):
80 if ( (waveform_picker_regs->status & 0x7) == 0x7 ){ // f2 f1 and f0 are full
78 if ( (waveform_picker_regs->status & 0xff8) != 0x00) // [1000] check the error bits
79 {
80 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 );
81 }
82 if ( (waveform_picker_regs->status & 0x07) == 0x07) // [0111] check the f2, f1, f0 full bits
83 {
81 84 // change F0 ring node
82 85 ring_node_to_send_swf_f0 = current_ring_node_f0;
83 86 current_ring_node_f0 = current_ring_node_f0->next;
84 87 waveform_picker_regs->addr_data_f0 = current_ring_node_f0->buffer_address;
85 88 // change F1 ring node
86 89 ring_node_to_send_swf_f1 = current_ring_node_f1;
87 90 current_ring_node_f1 = current_ring_node_f1->next;
88 91 waveform_picker_regs->addr_data_f1 = current_ring_node_f1->buffer_address;
89 92 // change F2 ring node
90 93 ring_node_to_send_swf_f2 = current_ring_node_f2;
91 94 current_ring_node_f2 = current_ring_node_f2->next;
92 95 waveform_picker_regs->addr_data_f2 = current_ring_node_f2->buffer_address;
93 // send an event to the WFRM task
96 //
94 97 if (rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_NORMAL ) != RTEMS_SUCCESSFUL) {
95 98 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 );
96 99 }
97 // nb_swf = nb_swf + 1;
98 // if (nb_swf == 2)
99 // {
100 // reset_wfp_burst_enable();
101 // }
102 // else
103 // {
104 100 waveform_picker_regs->status = waveform_picker_regs->status & 0xfffff888; // [1000 1000 1000]
105 // }
106 101 }
102
107 103 break;
108 104
109 105 //******
110 106 // BURST
111 107 case(LFR_MODE_BURST):
112 108 if ( (waveform_picker_regs->status & 0x04) == 0x04 ){ // [0100] check the f2 full bit
113 109 // (1) change the receiving buffer for the waveform picker
114 110 ring_node_to_send_cwf_f2 = current_ring_node_f2;
115 111 current_ring_node_f2 = current_ring_node_f2->next;
116 112 waveform_picker_regs->addr_data_f2 = current_ring_node_f2->buffer_address;
117 113 // (2) send an event for the waveforms transmission
118 114 if (rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_BURST ) != RTEMS_SUCCESSFUL) {
119 115 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 );
120 116 }
121 117 waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffbbb; // [1111 1011 1011 1011] f2 bit = 0
122 118 }
123 119 break;
124 120
125 121 //*****
126 122 // SBM1
127 123 case(LFR_MODE_SBM1):
128 124 if ( (waveform_picker_regs->status & 0x02) == 0x02 ) { // [0010] check the f1 full bit
129 125 // (1) change the receiving buffer for the waveform picker
130 126 ring_node_to_send_cwf_f1 = current_ring_node_f1;
131 127 current_ring_node_f1 = current_ring_node_f1->next;
132 128 waveform_picker_regs->addr_data_f1 = current_ring_node_f1->buffer_address;
133 129 // (2) send an event for the waveforms transmission
134 130 if (rtems_event_send( Task_id[TASKID_CWF1], RTEMS_EVENT_MODE_SBM1 ) != RTEMS_SUCCESSFUL) {
135 131 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 );
136 132 }
137 133 waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffddd; // [1111 1101 1101 1101] f1 bit = 0
138 134 }
139 135 if ( (waveform_picker_regs->status & 0x01) == 0x01 ) { // [0001] check the f0 full bit
140 136 ring_node_to_send_swf_f1 = current_ring_node_f1->previous;
141 137 }
142 138 if ( (waveform_picker_regs->status & 0x04) == 0x04 ) { // [0100] check the f2 full bit
143 139 if (rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_NORMAL ) != RTEMS_SUCCESSFUL) {
144 140 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 );
145 141 }
146 142 waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffaaa; // [1111 1010 1010 1010] f2 and f0 bits = 0
147 143 }
148 144 break;
149 145
150 146 //*****
151 147 // SBM2
152 148 case(LFR_MODE_SBM2):
153 149 if ( (waveform_picker_regs->status & 0x04) == 0x04 ){ // [0100] check the f2 full bit
154 150 // (1) change the receiving buffer for the waveform picker
155 151 ring_node_to_send_cwf_f2 = current_ring_node_f2;
156 152 current_ring_node_f2 = current_ring_node_f2->next;
157 153 waveform_picker_regs->addr_data_f2 = current_ring_node_f2->buffer_address;
158 154 // (2) send an event for the waveforms transmission
159 155 if (rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_SBM2 ) != RTEMS_SUCCESSFUL) {
160 156 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 );
161 157 }
162 158 waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffbbb; // [1111 1011 1011 1011] f2 bit = 0
163 159 }
164 160 if ( (waveform_picker_regs->status & 0x01) == 0x01 ) { // [0001] check the f0 full bit
165 161 ring_node_to_send_swf_f2 = current_ring_node_f2->previous;
166 162 }
167 163 if ( (waveform_picker_regs->status & 0x02) == 0x02 ) { // [0010] check the f1 full bit
168 164 if (rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_NORMAL ) != RTEMS_SUCCESSFUL) {
169 165 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 );
170 166 }
171 167 waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffccc; // [1111 1100 1100 1100] f1, f0 bits = 0
172 168 }
173 169 break;
174 170
175 171 //********
176 172 // DEFAULT
177 173 default:
178 174 break;
179 175 }
180 176 }
181 177
182 178 rtems_task wfrm_task(rtems_task_argument argument) //used with the waveform picker VHDL IP
183 179 {
184 180 /** This RTEMS task is dedicated to the transmission of snapshots of the NORMAL mode.
185 181 *
186 182 * @param unused is the starting argument of the RTEMS task
187 183 *
188 184 * The following data packets are sent by this task:
189 185 * - TM_LFR_SCIENCE_NORMAL_SWF_F0
190 186 * - TM_LFR_SCIENCE_NORMAL_SWF_F1
191 187 * - TM_LFR_SCIENCE_NORMAL_SWF_F2
192 188 *
193 189 */
194 190
195 191 rtems_event_set event_out;
196 192 rtems_id queue_id;
197 193 rtems_status_code status;
198 194
199 195 init_header_snapshot_wf_table( SID_NORM_SWF_F0, headerSWF_F0 );
200 196 init_header_snapshot_wf_table( SID_NORM_SWF_F1, headerSWF_F1 );
201 197 init_header_snapshot_wf_table( SID_NORM_SWF_F2, headerSWF_F2 );
202 198
203 199 init_waveforms();
204 200
205 201 status = get_message_queue_id_send( &queue_id );
206 202 if (status != RTEMS_SUCCESSFUL)
207 203 {
208 204 PRINTF1("in WFRM *** ERR get_message_queue_id_send %d\n", status)
209 205 }
210 206
211 207 BOOT_PRINTF("in WFRM ***\n")
212 208
213 209 while(1){
214 210 // wait for an RTEMS_EVENT
215 211 rtems_event_receive(RTEMS_EVENT_MODE_NORMAL | RTEMS_EVENT_MODE_SBM1
216 | RTEMS_EVENT_MODE_SBM2 | RTEMS_EVENT_MODE_SBM2_WFRM,
212 | RTEMS_EVENT_MODE_SBM2 | RTEMS_EVENT_MODE_SBM2_WFRM
213 | RTEMS_EVENT_MODE_NORMAL_SWF_F0
214 | RTEMS_EVENT_MODE_NORMAL_SWF_F1
215 | RTEMS_EVENT_MODE_NORMAL_SWF_F2,
217 216 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
218 217 if (event_out == RTEMS_EVENT_MODE_NORMAL)
219 218 {
220 PRINTF1("status %x\n", waveform_picker_regs->status )
221 219 send_waveform_SWF((volatile int*) ring_node_to_send_swf_f0->buffer_address, SID_NORM_SWF_F0, headerSWF_F0, queue_id);
222 220 send_waveform_SWF((volatile int*) ring_node_to_send_swf_f1->buffer_address, SID_NORM_SWF_F1, headerSWF_F1, queue_id);
223 221 send_waveform_SWF((volatile int*) ring_node_to_send_swf_f2->buffer_address, SID_NORM_SWF_F2, headerSWF_F2, queue_id);
224 waveform_picker_regs->status = waveform_picker_regs->status & 0xfffff888; // [1000 1000 1000]
222 }
223 if ( (event_out & RTEMS_EVENT_MODE_NORMAL_SWF_F0) == RTEMS_EVENT_MODE_NORMAL_SWF_F0)
224 {
225 send_waveform_SWF((volatile int*) ring_node_to_send_swf_f0->buffer_address, SID_NORM_SWF_F0, headerSWF_F0, queue_id);
225 226 }
226 else
227 if ( (event_out & RTEMS_EVENT_MODE_NORMAL_SWF_F1) == RTEMS_EVENT_MODE_NORMAL_SWF_F1)
227 228 {
228 PRINTF("in WFRM *** unexpected event")
229 send_waveform_SWF((volatile int*) ring_node_to_send_swf_f1->buffer_address, SID_NORM_SWF_F1, headerSWF_F1, queue_id);
230 }
231 if ( (event_out & RTEMS_EVENT_MODE_NORMAL_SWF_F2) == RTEMS_EVENT_MODE_NORMAL_SWF_F2)
232 {
233 send_waveform_SWF((volatile int*) ring_node_to_send_swf_f2->buffer_address, SID_NORM_SWF_F2, headerSWF_F2, queue_id);
229 234 }
230 235 }
231 236 }
232 237
233 238 rtems_task cwf3_task(rtems_task_argument argument) //used with the waveform picker VHDL IP
234 239 {
235 240 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f3.
236 241 *
237 242 * @param unused is the starting argument of the RTEMS task
238 243 *
239 244 * The following data packet is sent by this task:
240 245 * - TM_LFR_SCIENCE_NORMAL_CWF_F3
241 246 *
242 247 */
243 248
244 249 rtems_event_set event_out;
245 250 rtems_id queue_id;
246 251 rtems_status_code status;
247 252
248 253 init_header_continuous_wf_table( SID_NORM_CWF_LONG_F3, headerCWF_F3 );
249 254 init_header_continuous_cwf3_light_table( headerCWF_F3_light );
250 255
251 256 status = get_message_queue_id_send( &queue_id );
252 257 if (status != RTEMS_SUCCESSFUL)
253 258 {
254 259 PRINTF1("in CWF3 *** ERR get_message_queue_id_send %d\n", status)
255 260 }
256 261
257 262 BOOT_PRINTF("in CWF3 ***\n")
258 263
259 264 while(1){
260 265 // wait for an RTEMS_EVENT
261 266 rtems_event_receive( RTEMS_EVENT_0,
262 267 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
263 268 PRINTF("send CWF F3 \n")
264 269 if (waveform_picker_regs->addr_data_f3 == (int) wf_cont_f3_a) {
265 270 if ( (parameter_dump_packet.sy_lfr_n_cwf_long_f3 & 0x01) == 0x01)
266 271 {
267 272 send_waveform_CWF( wf_cont_f3_b, SID_NORM_CWF_LONG_F3, headerCWF_F3, queue_id );
268 273 }
269 274 else
270 275 {
271 276 send_waveform_CWF3_light( wf_cont_f3_b, headerCWF_F3_light, queue_id );
272 277 }
273 278 }
274 279 else
275 280 {
276 281 if ( (parameter_dump_packet.sy_lfr_n_cwf_long_f3 & 0x01) == 0x00)
277 282 {
278 283 send_waveform_CWF( wf_cont_f3_a, SID_NORM_CWF_LONG_F3, headerCWF_F3, queue_id );
279 284 }
280 285 else
281 286 {
282 287 send_waveform_CWF3_light( wf_cont_f3_a, headerCWF_F3_light, queue_id );
283 288 }
284 289
285 290 }
286 291 }
287 292 }
288 293
289 294 rtems_task cwf2_task(rtems_task_argument argument) // ONLY USED IN BURST AND SBM2
290 295 {
291 296 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f2.
292 297 *
293 298 * @param unused is the starting argument of the RTEMS task
294 299 *
295 300 * The following data packet is sent by this function:
296 301 * - TM_LFR_SCIENCE_BURST_CWF_F2
297 302 * - TM_LFR_SCIENCE_SBM2_CWF_F2
298 303 *
299 304 */
300 305
301 306 rtems_event_set event_out;
302 307 rtems_id queue_id;
303 308 rtems_status_code status;
304 309
305 310 init_header_continuous_wf_table( SID_BURST_CWF_F2, headerCWF_F2_BURST );
306 311 init_header_continuous_wf_table( SID_SBM2_CWF_F2, headerCWF_F2_SBM2 );
307 312
308 313 status = get_message_queue_id_send( &queue_id );
309 314 if (status != RTEMS_SUCCESSFUL)
310 315 {
311 316 PRINTF1("in CWF2 *** ERR get_message_queue_id_send %d\n", status)
312 317 }
313 318
314 319 BOOT_PRINTF("in CWF2 ***\n")
315 320
316 321 while(1){
317 322 // wait for an RTEMS_EVENT
318 323 rtems_event_receive( RTEMS_EVENT_MODE_BURST | RTEMS_EVENT_MODE_SBM2,
319 324 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
320 325 if (event_out == RTEMS_EVENT_MODE_BURST)
321 326 {
322 327 send_waveform_CWF( (volatile int *) ring_node_to_send_cwf_f2->buffer_address, SID_BURST_CWF_F2, headerCWF_F2_BURST, queue_id );
323 328 }
324 329 if (event_out == RTEMS_EVENT_MODE_SBM2)
325 330 {
326 331 send_waveform_CWF( (volatile int *) ring_node_to_send_cwf_f2->buffer_address, SID_SBM2_CWF_F2, headerCWF_F2_SBM2, queue_id );
327 332 }
328 333 }
329 334 }
330 335
331 336 rtems_task cwf1_task(rtems_task_argument argument) // ONLY USED IN SBM1
332 337 {
333 338 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f1.
334 339 *
335 340 * @param unused is the starting argument of the RTEMS task
336 341 *
337 342 * The following data packet is sent by this function:
338 343 * - TM_LFR_SCIENCE_SBM1_CWF_F1
339 344 *
340 345 */
341 346
342 347 rtems_event_set event_out;
343 348 rtems_id queue_id;
344 349 rtems_status_code status;
345 350
346 351 init_header_continuous_wf_table( SID_SBM1_CWF_F1, headerCWF_F1 );
347 352
348 353 status = get_message_queue_id_send( &queue_id );
349 354 if (status != RTEMS_SUCCESSFUL)
350 355 {
351 356 PRINTF1("in CWF1 *** ERR get_message_queue_id_send %d\n", status)
352 357 }
353 358
354 359 BOOT_PRINTF("in CWF1 ***\n")
355 360
356 361 while(1){
357 362 // wait for an RTEMS_EVENT
358 363 rtems_event_receive( RTEMS_EVENT_MODE_SBM1,
359 364 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
360 365 send_waveform_CWF( (volatile int*) ring_node_to_send_cwf_f1->buffer_address, SID_SBM1_CWF_F1, headerCWF_F1, queue_id );
361 366 }
362 367 }
363 368
364 369 //******************
365 370 // general functions
366 371 void init_waveforms( void )
367 372 {
368 373 int i = 0;
369 374
370 375 for (i=0; i< NB_SAMPLES_PER_SNAPSHOT; i++)
371 376 {
372 377 //***
373 378 // F0
374 379 // wf_snap_f0[ (i* NB_WORDS_SWF_BLK) + 0 + TIME_OFFSET ] = 0x88887777; //
375 380 // wf_snap_f0[ (i* NB_WORDS_SWF_BLK) + 1 + TIME_OFFSET ] = 0x22221111; //
376 381 // wf_snap_f0[ (i* NB_WORDS_SWF_BLK) + 2 + TIME_OFFSET ] = 0x44443333; //
377 382
378 383 //***
379 384 // F1
380 385 // wf_snap_f1[ (i* NB_WORDS_SWF_BLK) + 0 + TIME_OFFSET ] = 0x22221111;
381 386 // wf_snap_f1[ (i* NB_WORDS_SWF_BLK) + 1 + TIME_OFFSET ] = 0x44443333;
382 387 // wf_snap_f1[ (i* NB_WORDS_SWF_BLK) + 2 + TIME_OFFSET ] = 0xaaaa0000;
383 388
384 389 //***
385 390 // F2
386 391 // wf_snap_f2[ (i* NB_WORDS_SWF_BLK) + 0 + TIME_OFFSET ] = 0x44443333;
387 392 // wf_snap_f2[ (i* NB_WORDS_SWF_BLK) + 1 + TIME_OFFSET ] = 0x22221111;
388 393 // wf_snap_f2[ (i* NB_WORDS_SWF_BLK) + 2 + TIME_OFFSET ] = 0xaaaa0000;
389 394
390 395 //***
391 396 // F3
392 397 // wf_cont_f3[ (i* NB_WORDS_SWF_BLK) + 0 ] = val1;
393 398 // wf_cont_f3[ (i* NB_WORDS_SWF_BLK) + 1 ] = val2;
394 399 // wf_cont_f3[ (i* NB_WORDS_SWF_BLK) + 2 ] = 0xaaaa0000;
395 400 }
396 401 }
397 402
398 403 void init_waveform_rings( void )
399 404 {
400 405 unsigned char i;
401 406
402 407 // F0 RING
403 408 waveform_ring_f0[0].next = (ring_node*) &waveform_ring_f0[1];
404 409 waveform_ring_f0[0].previous = (ring_node*) &waveform_ring_f0[NB_RING_NODES_F0-1];
405 410 waveform_ring_f0[0].buffer_address = (int) &wf_snap_f0[0][0];
406 411
407 412 waveform_ring_f0[NB_RING_NODES_F0-1].next = (ring_node*) &waveform_ring_f0[0];
408 413 waveform_ring_f0[NB_RING_NODES_F0-1].previous = (ring_node*) &waveform_ring_f0[NB_RING_NODES_F0-2];
409 414 waveform_ring_f0[NB_RING_NODES_F0-1].buffer_address = (int) &wf_snap_f0[NB_RING_NODES_F0-1][0];
410 415
411 416 for(i=1; i<NB_RING_NODES_F0-1; i++)
412 417 {
413 418 waveform_ring_f0[i].next = (ring_node*) &waveform_ring_f0[i+1];
414 419 waveform_ring_f0[i].previous = (ring_node*) &waveform_ring_f0[i-1];
415 420 waveform_ring_f0[i].buffer_address = (int) &wf_snap_f0[i][0];
416 421 }
417 422
418 423 // F1 RING
419 424 waveform_ring_f1[0].next = (ring_node*) &waveform_ring_f1[1];
420 425 waveform_ring_f1[0].previous = (ring_node*) &waveform_ring_f1[NB_RING_NODES_F1-1];
421 426 waveform_ring_f1[0].buffer_address = (int) &wf_snap_f1[0][0];
422 427
423 428 waveform_ring_f1[NB_RING_NODES_F1-1].next = (ring_node*) &waveform_ring_f1[0];
424 429 waveform_ring_f1[NB_RING_NODES_F1-1].previous = (ring_node*) &waveform_ring_f1[NB_RING_NODES_F1-2];
425 430 waveform_ring_f1[NB_RING_NODES_F1-1].buffer_address = (int) &wf_snap_f1[NB_RING_NODES_F1-1][0];
426 431
427 432 for(i=1; i<NB_RING_NODES_F1-1; i++)
428 433 {
429 434 waveform_ring_f1[i].next = (ring_node*) &waveform_ring_f1[i+1];
430 435 waveform_ring_f1[i].previous = (ring_node*) &waveform_ring_f1[i-1];
431 436 waveform_ring_f1[i].buffer_address = (int) &wf_snap_f1[i][0];
432 437 }
433 438
434 439 // F2 RING
435 440 waveform_ring_f2[0].next = (ring_node*) &waveform_ring_f2[1];
436 441 waveform_ring_f2[0].previous = (ring_node*) &waveform_ring_f2[NB_RING_NODES_F2-1];
437 442 waveform_ring_f2[0].buffer_address = (int) &wf_snap_f2[0][0];
438 443
439 444 waveform_ring_f2[NB_RING_NODES_F2-1].next = (ring_node*) &waveform_ring_f2[0];
440 445 waveform_ring_f2[NB_RING_NODES_F2-1].previous = (ring_node*) &waveform_ring_f2[NB_RING_NODES_F2-2];
441 446 waveform_ring_f2[NB_RING_NODES_F2-1].buffer_address = (int) &wf_snap_f2[NB_RING_NODES_F2-1][0];
442 447
443 448 for(i=1; i<NB_RING_NODES_F2-1; i++)
444 449 {
445 450 waveform_ring_f2[i].next = (ring_node*) &waveform_ring_f2[i+1];
446 451 waveform_ring_f2[i].previous = (ring_node*) &waveform_ring_f2[i-1];
447 452 waveform_ring_f2[i].buffer_address = (int) &wf_snap_f2[i][0];
448 453 }
449 454
450 455 DEBUG_PRINTF1("waveform_ring_f0 @%x\n", (unsigned int) waveform_ring_f0)
451 456 DEBUG_PRINTF1("waveform_ring_f1 @%x\n", (unsigned int) waveform_ring_f1)
452 457 DEBUG_PRINTF1("waveform_ring_f2 @%x\n", (unsigned int) waveform_ring_f2)
453 458
454 459 }
455 460
456 461 void reset_current_ring_nodes( void )
457 462 {
458 463 current_ring_node_f0 = waveform_ring_f0;
459 464 ring_node_to_send_swf_f0 = waveform_ring_f0;
460 465
461 466 current_ring_node_f1 = waveform_ring_f1;
462 467 ring_node_to_send_cwf_f1 = waveform_ring_f1;
463 468 ring_node_to_send_swf_f1 = waveform_ring_f1;
464 469
465 470 current_ring_node_f2 = waveform_ring_f2;
466 471 ring_node_to_send_cwf_f2 = waveform_ring_f2;
467 472 ring_node_to_send_swf_f2 = waveform_ring_f2;
468 473 }
469 474
470 475 int init_header_snapshot_wf_table( unsigned int sid, Header_TM_LFR_SCIENCE_SWF_t *headerSWF)
471 476 {
472 477 unsigned char i;
473 478
474 479 for (i=0; i<7; i++)
475 480 {
476 481 headerSWF[ i ].targetLogicalAddress = CCSDS_DESTINATION_ID;
477 482 headerSWF[ i ].protocolIdentifier = CCSDS_PROTOCOLE_ID;
478 483 headerSWF[ i ].reserved = DEFAULT_RESERVED;
479 484 headerSWF[ i ].userApplication = CCSDS_USER_APP;
480 485 headerSWF[ i ].packetID[0] = (unsigned char) (TM_PACKET_ID_SCIENCE_NORMAL_BURST >> 8);
481 486 headerSWF[ i ].packetID[1] = (unsigned char) (TM_PACKET_ID_SCIENCE_NORMAL_BURST);
482 487 headerSWF[ i ].packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
483 488 if (i == 6)
484 489 {
485 490 headerSWF[ i ].packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_224 >> 8);
486 491 headerSWF[ i ].packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_224 );
487 492 headerSWF[ i ].blkNr[0] = (unsigned char) (BLK_NR_224 >> 8);
488 493 headerSWF[ i ].blkNr[1] = (unsigned char) (BLK_NR_224 );
489 494 }
490 495 else
491 496 {
492 497 headerSWF[ i ].packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_304 >> 8);
493 498 headerSWF[ i ].packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_304 );
494 499 headerSWF[ i ].blkNr[0] = (unsigned char) (BLK_NR_304 >> 8);
495 500 headerSWF[ i ].blkNr[1] = (unsigned char) (BLK_NR_304 );
496 501 }
497 502 headerSWF[ i ].packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
498 503 headerSWF[ i ].pktCnt = DEFAULT_PKTCNT; // PKT_CNT
499 504 headerSWF[ i ].pktNr = i+1; // PKT_NR
500 505 // DATA FIELD HEADER
501 506 headerSWF[ i ].spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
502 507 headerSWF[ i ].serviceType = TM_TYPE_LFR_SCIENCE; // service type
503 508 headerSWF[ i ].serviceSubType = TM_SUBTYPE_LFR_SCIENCE; // service subtype
504 509 headerSWF[ i ].destinationID = TM_DESTINATION_ID_GROUND;
505 510 // AUXILIARY DATA HEADER
506 511 headerSWF[ i ].time[0] = 0x00;
507 512 headerSWF[ i ].time[0] = 0x00;
508 513 headerSWF[ i ].time[0] = 0x00;
509 514 headerSWF[ i ].time[0] = 0x00;
510 515 headerSWF[ i ].time[0] = 0x00;
511 516 headerSWF[ i ].time[0] = 0x00;
512 517 headerSWF[ i ].sid = sid;
513 518 headerSWF[ i ].hkBIA = DEFAULT_HKBIA;
514 519 }
515 520 return LFR_SUCCESSFUL;
516 521 }
517 522
518 523 int init_header_continuous_wf_table( unsigned int sid, Header_TM_LFR_SCIENCE_CWF_t *headerCWF )
519 524 {
520 525 unsigned int i;
521 526
522 527 for (i=0; i<7; i++)
523 528 {
524 529 headerCWF[ i ].targetLogicalAddress = CCSDS_DESTINATION_ID;
525 530 headerCWF[ i ].protocolIdentifier = CCSDS_PROTOCOLE_ID;
526 531 headerCWF[ i ].reserved = DEFAULT_RESERVED;
527 532 headerCWF[ i ].userApplication = CCSDS_USER_APP;
528 533 if ( (sid == SID_SBM1_CWF_F1) || (sid == SID_SBM2_CWF_F2) )
529 534 {
530 535 headerCWF[ i ].packetID[0] = (unsigned char) (TM_PACKET_ID_SCIENCE_SBM1_SBM2 >> 8);
531 536 headerCWF[ i ].packetID[1] = (unsigned char) (TM_PACKET_ID_SCIENCE_SBM1_SBM2);
532 537 }
533 538 else
534 539 {
535 540 headerCWF[ i ].packetID[0] = (unsigned char) (TM_PACKET_ID_SCIENCE_NORMAL_BURST >> 8);
536 541 headerCWF[ i ].packetID[1] = (unsigned char) (TM_PACKET_ID_SCIENCE_NORMAL_BURST);
537 542 }
538 543 headerCWF[ i ].packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
539 544 headerCWF[ i ].packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
540 545 headerCWF[ i ].packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
541 546 headerCWF[ i ].blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
542 547 headerCWF[ i ].blkNr[1] = (unsigned char) (BLK_NR_CWF );
543 548 headerCWF[ i ].packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
544 549 // DATA FIELD HEADER
545 550 headerCWF[ i ].spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
546 551 headerCWF[ i ].serviceType = TM_TYPE_LFR_SCIENCE; // service type
547 552 headerCWF[ i ].serviceSubType = TM_SUBTYPE_LFR_SCIENCE; // service subtype
548 553 headerCWF[ i ].destinationID = TM_DESTINATION_ID_GROUND;
549 554 // AUXILIARY DATA HEADER
550 555 headerCWF[ i ].sid = sid;
551 556 headerCWF[ i ].hkBIA = DEFAULT_HKBIA;
552 557 headerCWF[ i ].time[0] = 0x00;
553 558 headerCWF[ i ].time[0] = 0x00;
554 559 headerCWF[ i ].time[0] = 0x00;
555 560 headerCWF[ i ].time[0] = 0x00;
556 561 headerCWF[ i ].time[0] = 0x00;
557 562 headerCWF[ i ].time[0] = 0x00;
558 563 }
559 564 return LFR_SUCCESSFUL;
560 565 }
561 566
562 567 int init_header_continuous_cwf3_light_table( Header_TM_LFR_SCIENCE_CWF_t *headerCWF )
563 568 {
564 569 unsigned int i;
565 570
566 571 for (i=0; i<7; i++)
567 572 {
568 573 headerCWF[ i ].targetLogicalAddress = CCSDS_DESTINATION_ID;
569 574 headerCWF[ i ].protocolIdentifier = CCSDS_PROTOCOLE_ID;
570 575 headerCWF[ i ].reserved = DEFAULT_RESERVED;
571 576 headerCWF[ i ].userApplication = CCSDS_USER_APP;
572 577
573 578 headerCWF[ i ].packetID[0] = (unsigned char) (TM_PACKET_ID_SCIENCE_NORMAL_BURST >> 8);
574 579 headerCWF[ i ].packetID[1] = (unsigned char) (TM_PACKET_ID_SCIENCE_NORMAL_BURST);
575 580
576 581 headerCWF[ i ].packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
577 582 headerCWF[ i ].packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_672 >> 8);
578 583 headerCWF[ i ].packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_672 );
579 584 headerCWF[ i ].blkNr[0] = (unsigned char) (BLK_NR_CWF_SHORT_F3 >> 8);
580 585 headerCWF[ i ].blkNr[1] = (unsigned char) (BLK_NR_CWF_SHORT_F3 );
581 586
582 587 headerCWF[ i ].packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
583 588 // DATA FIELD HEADER
584 589 headerCWF[ i ].spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
585 590 headerCWF[ i ].serviceType = TM_TYPE_LFR_SCIENCE; // service type
586 591 headerCWF[ i ].serviceSubType = TM_SUBTYPE_LFR_SCIENCE; // service subtype
587 592 headerCWF[ i ].destinationID = TM_DESTINATION_ID_GROUND;
588 593 // AUXILIARY DATA HEADER
589 594 headerCWF[ i ].sid = SID_NORM_CWF_F3;
590 595 headerCWF[ i ].hkBIA = DEFAULT_HKBIA;
591 596 headerCWF[ i ].time[0] = 0x00;
592 597 headerCWF[ i ].time[0] = 0x00;
593 598 headerCWF[ i ].time[0] = 0x00;
594 599 headerCWF[ i ].time[0] = 0x00;
595 600 headerCWF[ i ].time[0] = 0x00;
596 601 headerCWF[ i ].time[0] = 0x00;
597 602 }
598 603 return LFR_SUCCESSFUL;
599 604 }
600 605
601 606 int send_waveform_SWF( volatile int *waveform, unsigned int sid,
602 607 Header_TM_LFR_SCIENCE_SWF_t *headerSWF, rtems_id queue_id )
603 608 {
604 609 /** This function sends SWF CCSDS packets (F2, F1 or F0).
605 610 *
606 611 * @param waveform points to the buffer containing the data that will be send.
607 612 * @param sid is the source identifier of the data that will be sent.
608 613 * @param headerSWF points to a table of headers that have been prepared for the data transmission.
609 614 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
610 615 * contain information to setup the transmission of the data packets.
611 616 *
612 617 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
613 618 *
614 619 */
615 620
616 621 unsigned int i;
617 622 int ret;
618 623 unsigned int coarseTime;
619 624 unsigned int fineTime;
620 625 rtems_status_code status;
621 626 spw_ioctl_pkt_send spw_ioctl_send_SWF;
622 627
623 628 spw_ioctl_send_SWF.hlen = TM_HEADER_LEN + 4 + 12; // + 4 is for the protocole extra header, + 12 is for the auxiliary header
624 629 spw_ioctl_send_SWF.options = 0;
625 630
626 631 ret = LFR_DEFAULT;
627 632
628 633 PRINTF1("sid = %d, ", sid)
629 634 PRINTF2("coarse = %x, fine = %x\n", waveform[0], waveform[1])
630 635
631 636 for (i=0; i<7; i++) // send waveform
632 637 {
633 638 #ifdef VHDL_DEV
634 639 spw_ioctl_send_SWF.data = (char*) &waveform[ (i * BLK_NR_304 * NB_WORDS_SWF_BLK) + TIME_OFFSET];
635 640 #else
636 641 spw_ioctl_send_SWF.data = (char*) &waveform[ (i * BLK_NR_304 * NB_WORDS_SWF_BLK) ];
637 642 #endif
638 643 spw_ioctl_send_SWF.hdr = (char*) &headerSWF[ i ];
639 644 // BUILD THE DATA
640 645 if (i==6) {
641 646 spw_ioctl_send_SWF.dlen = BLK_NR_224 * NB_BYTES_SWF_BLK;
642 647 }
643 648 else {
644 649 spw_ioctl_send_SWF.dlen = BLK_NR_304 * NB_BYTES_SWF_BLK;
645 650 }
646 651 // SET PACKET SEQUENCE COUNTER
647 652 increment_seq_counter_source_id( headerSWF[ i ].packetSequenceControl, sid );
648 653 // SET PACKET TIME
649 654 #ifdef VHDL_DEV
650 655 coarseTime = waveform[0];
651 656 fineTime = waveform[1];
652 657 compute_acquisition_time( &coarseTime, &fineTime, sid, i);
653 658
654 659 headerSWF[ i ].acquisitionTime[0] = (unsigned char) (coarseTime >> 24 );
655 660 headerSWF[ i ].acquisitionTime[1] = (unsigned char) (coarseTime >> 16 );
656 661 headerSWF[ i ].acquisitionTime[2] = (unsigned char) (coarseTime >> 8 );
657 662 headerSWF[ i ].acquisitionTime[3] = (unsigned char) (coarseTime );
658 663 headerSWF[ i ].acquisitionTime[4] = (unsigned char) (fineTime >> 8 );
659 664 headerSWF[ i ].acquisitionTime[5] = (unsigned char) (fineTime );
660 665 #else
661 666 headerSWF[ i ].acquisitionTime[0] = (unsigned char) (time_management_regs->coarse_time>>24);
662 667 headerSWF[ i ].acquisitionTime[1] = (unsigned char) (time_management_regs->coarse_time>>16);
663 668 headerSWF[ i ].acquisitionTime[2] = (unsigned char) (time_management_regs->coarse_time>>8);
664 669 headerSWF[ i ].acquisitionTime[3] = (unsigned char) (time_management_regs->coarse_time);
665 670 headerSWF[ i ].acquisitionTime[4] = (unsigned char) (time_management_regs->fine_time>>8);
666 671 headerSWF[ i ].acquisitionTime[5] = (unsigned char) (time_management_regs->fine_time);
667 672 #endif
668 673 headerSWF[ i ].time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
669 674 headerSWF[ i ].time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
670 675 headerSWF[ i ].time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
671 676 headerSWF[ i ].time[3] = (unsigned char) (time_management_regs->coarse_time);
672 677 headerSWF[ i ].time[4] = (unsigned char) (time_management_regs->fine_time>>8);
673 678 headerSWF[ i ].time[5] = (unsigned char) (time_management_regs->fine_time);
674 679 // SEND PACKET
675 680 status = rtems_message_queue_send( queue_id, &spw_ioctl_send_SWF, ACTION_MSG_SPW_IOCTL_SEND_SIZE);
676 681 if (status != RTEMS_SUCCESSFUL) {
677 682 printf("%d-%d, ERR %d\n", sid, i, (int) status);
678 683 ret = LFR_DEFAULT;
679 684 }
680 685 rtems_task_wake_after(TIME_BETWEEN_TWO_SWF_PACKETS); // 300 ms between each packet => 7 * 3 = 21 packets => 6.3 seconds
681 686 }
682 687
683 688 return ret;
684 689 }
685 690
686 691 int send_waveform_CWF(volatile int *waveform, unsigned int sid,
687 692 Header_TM_LFR_SCIENCE_CWF_t *headerCWF, rtems_id queue_id)
688 693 {
689 694 /** This function sends CWF CCSDS packets (F2, F1 or F0).
690 695 *
691 696 * @param waveform points to the buffer containing the data that will be send.
692 697 * @param sid is the source identifier of the data that will be sent.
693 698 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
694 699 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
695 700 * contain information to setup the transmission of the data packets.
696 701 *
697 702 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
698 703 *
699 704 */
700 705
701 706 unsigned int i;
702 707 int ret;
703 708 unsigned char *coarseTimePtr;
704 709 unsigned char *fineTimePtr;
705 710 rtems_status_code status;
706 711 spw_ioctl_pkt_send spw_ioctl_send_CWF;
707 712
708 713 spw_ioctl_send_CWF.hlen = TM_HEADER_LEN + 4 + 10; // + 4 is for the protocole extra header, + 10 is for the auxiliary header
709 714 spw_ioctl_send_CWF.options = 0;
710 715
711 716 ret = LFR_DEFAULT;
712 717
713 718 for (i=0; i<7; i++) // send waveform
714 719 {
715 720 int coarseTime = 0x00;
716 721 int fineTime = 0x00;
717 722 #ifdef VHDL_DEV
718 723 spw_ioctl_send_CWF.data = (char*) &waveform[ (i * BLK_NR_CWF * NB_WORDS_SWF_BLK) + TIME_OFFSET];
719 724 #else
720 725 spw_ioctl_send_CWF.data = (char*) &waveform[ (i * BLK_NR_CWF * NB_WORDS_SWF_BLK) ];
721 726 #endif
722 727 spw_ioctl_send_CWF.hdr = (char*) &headerCWF[ i ];
723 728 // BUILD THE DATA
724 729 spw_ioctl_send_CWF.dlen = BLK_NR_CWF * NB_BYTES_SWF_BLK;
725 730 // SET PACKET SEQUENCE COUNTER
726 731 increment_seq_counter_source_id( headerCWF[ i ].packetSequenceControl, sid );
727 732 // SET PACKET TIME
728 733 #ifdef VHDL_DEV
729 734 coarseTimePtr = (unsigned char *) &waveform;
730 735 fineTimePtr = (unsigned char *) &waveform[1];
731 736 headerCWF[ i ].acquisitionTime[0] = coarseTimePtr[2];
732 737 headerCWF[ i ].acquisitionTime[1] = coarseTimePtr[3];
733 738 headerCWF[ i ].acquisitionTime[2] = coarseTimePtr[0];
734 739 headerCWF[ i ].acquisitionTime[3] = coarseTimePtr[1];
735 740 headerCWF[ i ].acquisitionTime[4] = fineTimePtr[0];
736 741 headerCWF[ i ].acquisitionTime[5] = fineTimePtr[1];
737 742 #else
738 743 coarseTime = time_management_regs->coarse_time;
739 744 fineTime = time_management_regs->fine_time;
740 745 headerCWF[ i ].acquisitionTime[0] = (unsigned char) (coarseTime>>24);
741 746 headerCWF[ i ].acquisitionTime[1] = (unsigned char) (coarseTime>>16);
742 747 headerCWF[ i ].acquisitionTime[2] = (unsigned char) (coarseTime>>8);
743 748 headerCWF[ i ].acquisitionTime[3] = (unsigned char) (coarseTime);
744 749 headerCWF[ i ].acquisitionTime[4] = (unsigned char) (fineTime>>8);
745 750 headerCWF[ i ].acquisitionTime[5] = (unsigned char) (fineTime);
746 751 #endif
747 752
748 753 headerCWF[ i ].time[0] = (unsigned char) (coarseTime>>24);
749 754 headerCWF[ i ].time[1] = (unsigned char) (coarseTime>>16);
750 755 headerCWF[ i ].time[2] = (unsigned char) (coarseTime>>8);
751 756 headerCWF[ i ].time[3] = (unsigned char) (coarseTime);
752 757 headerCWF[ i ].time[4] = (unsigned char) (fineTime>>8);
753 758 headerCWF[ i ].time[5] = (unsigned char) (fineTime);
754 759 // SEND PACKET
755 760 if (sid == SID_NORM_CWF_LONG_F3)
756 761 {
757 762 status = rtems_message_queue_send( queue_id, &spw_ioctl_send_CWF, sizeof(spw_ioctl_send_CWF));
758 763 if (status != RTEMS_SUCCESSFUL) {
759 764 printf("%d-%d, ERR %d\n", sid, i, (int) status);
760 765 ret = LFR_DEFAULT;
761 766 }
762 767 rtems_task_wake_after(TIME_BETWEEN_TWO_CWF3_PACKETS);
763 768 }
764 769 else
765 770 {
766 771 status = rtems_message_queue_send( queue_id, &spw_ioctl_send_CWF, sizeof(spw_ioctl_send_CWF));
767 772 if (status != RTEMS_SUCCESSFUL) {
768 773 printf("%d-%d, ERR %d\n", sid, i, (int) status);
769 774 ret = LFR_DEFAULT;
770 775 }
771 776 }
772 777 }
773 778
774 779 return ret;
775 780 }
776 781
777 782 int send_waveform_CWF3_light(volatile int *waveform, Header_TM_LFR_SCIENCE_CWF_t *headerCWF, rtems_id queue_id)
778 783 {
779 784 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
780 785 *
781 786 * @param waveform points to the buffer containing the data that will be send.
782 787 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
783 788 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
784 789 * contain information to setup the transmission of the data packets.
785 790 *
786 791 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
787 792 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
788 793 *
789 794 */
790 795
791 796 unsigned int i;
792 797 int ret;
793 798 unsigned char *coarseTimePtr;
794 799 unsigned char *fineTimePtr;
795 800 rtems_status_code status;
796 801 spw_ioctl_pkt_send spw_ioctl_send_CWF;
797 802 char *sample;
798 803
799 804 spw_ioctl_send_CWF.hlen = TM_HEADER_LEN + 4 + 10; // + 4 is for the protocole extra header, + 10 is for the auxiliary header
800 805 spw_ioctl_send_CWF.options = 0;
801 806
802 807 ret = LFR_DEFAULT;
803 808
804 809 //**********************
805 810 // BUILD CWF3_light DATA
806 811 for ( i=0; i< NB_SAMPLES_PER_SNAPSHOT; i++)
807 812 {
808 813 #ifdef VHDL_DEV
809 814 sample = (char*) &waveform[ (i * NB_WORDS_SWF_BLK) + TIME_OFFSET ];
810 815 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + TIME_OFFSET_IN_BYTES ] = sample[ 0 ];
811 816 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 1 + TIME_OFFSET_IN_BYTES ] = sample[ 1 ];
812 817 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 2 + TIME_OFFSET_IN_BYTES ] = sample[ 2 ];
813 818 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 3 + TIME_OFFSET_IN_BYTES ] = sample[ 3 ];
814 819 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 4 + TIME_OFFSET_IN_BYTES ] = sample[ 4 ];
815 820 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 5 + TIME_OFFSET_IN_BYTES ] = sample[ 5 ];
816 821 #else
817 822 sample = (char*) &waveform[ i * NB_WORDS_SWF_BLK ];
818 823 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) ] = sample[ 0 ];
819 824 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 1 ] = sample[ 1 ];
820 825 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 2 ] = sample[ 2 ];
821 826 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 3 ] = sample[ 3 ];
822 827 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 4 ] = sample[ 4 ];
823 828 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 5 ] = sample[ 5 ];
824 829 #endif
825 830 }
826 831
827 832 //*********************
828 833 // SEND CWF3_light DATA
829 834
830 835 for (i=0; i<7; i++) // send waveform
831 836 {
832 837 int coarseTime = 0x00;
833 838 int fineTime = 0x00;
834 839
835 840 #ifdef VHDL_DEV
836 841 spw_ioctl_send_CWF.data = (char*) &wf_cont_f3_light[ (i * BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK) + TIME_OFFSET_IN_BYTES];
837 842 #else
838 843 spw_ioctl_send_CWF.data = (char*) &wf_cont_f3_light[ (i * BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK) ];
839 844 #endif
840 845 spw_ioctl_send_CWF.hdr = (char*) &headerCWF[ i ];
841 846 // BUILD THE DATA
842 847 spw_ioctl_send_CWF.dlen = BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK;
843 848 // SET PACKET SEQUENCE COUNTER
844 849 increment_seq_counter_source_id( headerCWF[ i ].packetSequenceControl, SID_NORM_CWF_F3 );
845 850 // SET PACKET TIME
846 851 #ifdef VHDL_DEV
847 852 coarseTimePtr = (unsigned char *) &waveform;
848 853 fineTimePtr = (unsigned char *) &waveform[1];
849 854 headerCWF[ i ].acquisitionTime[0] = coarseTimePtr[2];
850 855 headerCWF[ i ].acquisitionTime[1] = coarseTimePtr[3];
851 856 headerCWF[ i ].acquisitionTime[2] = coarseTimePtr[0];
852 857 headerCWF[ i ].acquisitionTime[3] = coarseTimePtr[1];
853 858 headerCWF[ i ].acquisitionTime[4] = fineTimePtr[0];
854 859 headerCWF[ i ].acquisitionTime[5] = fineTimePtr[1];
855 860 #else
856 861 coarseTime = time_management_regs->coarse_time;
857 862 fineTime = time_management_regs->fine_time;
858 863 headerCWF[ i ].acquisitionTime[0] = (unsigned char) (coarseTime>>24);
859 864 headerCWF[ i ].acquisitionTime[1] = (unsigned char) (coarseTime>>16);
860 865 headerCWF[ i ].acquisitionTime[2] = (unsigned char) (coarseTime>>8);
861 866 headerCWF[ i ].acquisitionTime[3] = (unsigned char) (coarseTime);
862 867 headerCWF[ i ].acquisitionTime[4] = (unsigned char) (fineTime>>8);
863 868 headerCWF[ i ].acquisitionTime[5] = (unsigned char) (fineTime);
864 869 #endif
865 870 headerCWF[ i ].time[0] = (unsigned char) (coarseTime>>24);
866 871 headerCWF[ i ].time[1] = (unsigned char) (coarseTime>>16);
867 872 headerCWF[ i ].time[2] = (unsigned char) (coarseTime>>8);
868 873 headerCWF[ i ].time[3] = (unsigned char) (coarseTime);
869 874 headerCWF[ i ].time[4] = (unsigned char) (fineTime>>8);
870 875 headerCWF[ i ].time[5] = (unsigned char) (fineTime);
871 876 // SEND PACKET
872 877 status = rtems_message_queue_send( queue_id, &spw_ioctl_send_CWF, sizeof(spw_ioctl_send_CWF));
873 878 if (status != RTEMS_SUCCESSFUL) {
874 879 printf("%d-%d, ERR %d\n", SID_NORM_CWF_F3, i, (int) status);
875 880 ret = LFR_DEFAULT;
876 881 }
877 882 rtems_task_wake_after(TIME_BETWEEN_TWO_CWF3_PACKETS);
878 883 }
879 884
880 885 return ret;
881 886 }
882 887
883 888 void compute_acquisition_time( unsigned int *coarseTime, unsigned int *fineTime, unsigned int sid, unsigned char pa_lfr_pkt_nr )
884 889 {
885 890 unsigned long long int acquisitionTimeAsLong;
886 891 unsigned char acquisitionTime[6];
887 892 float deltaT = 0.;
888 893
889 894 acquisitionTime[0] = (unsigned char) ( *coarseTime >> 8 );
890 895 acquisitionTime[1] = (unsigned char) ( *coarseTime );
891 896 acquisitionTime[2] = (unsigned char) ( *coarseTime >> 24 );
892 897 acquisitionTime[3] = (unsigned char) ( *coarseTime >> 16 );
893 898 acquisitionTime[4] = (unsigned char) ( *fineTime >> 24 );
894 899 acquisitionTime[5] = (unsigned char) ( *fineTime >> 16 );
895 900
896 901 acquisitionTimeAsLong = ( (unsigned long long int) acquisitionTime[0] << 40 )
897 902 + ( (unsigned long long int) acquisitionTime[1] << 32 )
898 903 + ( acquisitionTime[2] << 24 )
899 904 + ( acquisitionTime[3] << 16 )
900 905 + ( acquisitionTime[4] << 8 )
901 906 + ( acquisitionTime[5] );
902 907
903 908 switch( sid )
904 909 {
905 910 case SID_NORM_SWF_F0:
906 911 deltaT = ( (float ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 24576. ;
907 912 break;
908 913
909 914 case SID_NORM_SWF_F1:
910 915 deltaT = ( (float ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 4096. ;
911 916 break;
912 917
913 918 case SID_NORM_SWF_F2:
914 919 deltaT = ( (float ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 256. ;
915 920 break;
916 921
917 922 default:
918 923 deltaT = 0.;
919 924 break;
920 925 }
921 926
922 927 acquisitionTimeAsLong = acquisitionTimeAsLong + (unsigned long long int) deltaT;
923 928
924 929 *coarseTime = (unsigned int) (acquisitionTimeAsLong >> 16);
925 930 *fineTime = (unsigned int) (acquisitionTimeAsLong & 0xffff);
926 931 }
927 932
928 933 //**************
929 934 // wfp registers
930 935 void set_wfp_data_shaping()
931 936 {
932 937 /** This function sets the data_shaping register of the waveform picker module.
933 938 *
934 939 * The value is read from one field of the parameter_dump_packet structure:\n
935 940 * bw_sp0_sp1_r0_r1
936 941 *
937 942 */
938 943
939 944 unsigned char data_shaping;
940 945
941 946 // get the parameters for the data shaping [BW SP0 SP1 R0 R1] in sy_lfr_common1 and configure the register
942 947 // waveform picker : [R1 R0 SP1 SP0 BW]
943 948
944 949 data_shaping = parameter_dump_packet.bw_sp0_sp1_r0_r1;
945 950
946 951 #ifdef GSA
947 952 #else
948 953 waveform_picker_regs->data_shaping =
949 954 ( (data_shaping & 0x10) >> 4 ) // BW
950 955 + ( (data_shaping & 0x08) >> 2 ) // SP0
951 956 + ( (data_shaping & 0x04) ) // SP1
952 957 + ( (data_shaping & 0x02) << 2 ) // R0
953 958 + ( (data_shaping & 0x01) << 4 ); // R1
954 959 #endif
955 960 }
956 961
957 962 char set_wfp_delta_snapshot()
958 963 {
959 964 /** This function sets the delta_snapshot register of the waveform picker module.
960 965 *
961 966 * The value is read from two (unsigned char) of the parameter_dump_packet structure:
962 967 * - sy_lfr_n_swf_p[0]
963 968 * - sy_lfr_n_swf_p[1]
964 969 *
965 970 */
966 971
967 972 char ret;
968 973 unsigned int delta_snapshot;
969 974 unsigned int aux;
970 975
971 976 aux = 0;
972 977 ret = LFR_DEFAULT;
973 978
974 979 delta_snapshot = parameter_dump_packet.sy_lfr_n_swf_p[0]*256
975 980 + parameter_dump_packet.sy_lfr_n_swf_p[1];
976 981
977 982 #ifdef GSA
978 983 #else
979 984 if ( delta_snapshot < MIN_DELTA_SNAPSHOT )
980 985 {
981 986 aux = MIN_DELTA_SNAPSHOT;
982 987 ret = LFR_DEFAULT;
983 988 }
984 989 else
985 990 {
986 991 aux = delta_snapshot ;
987 992 ret = LFR_SUCCESSFUL;
988 993 }
989 994 waveform_picker_regs->delta_snapshot = aux - 1; // max 2 bytes
990 995 #endif
991 996
992 997 return ret;
993 998 }
994 999
995 1000 #ifdef VHDL_DEV
996 1001 void set_wfp_burst_enable_register( unsigned char mode )
997 1002 {
998 1003 /** This function sets the waveform picker burst_enable register depending on the mode.
999 1004 *
1000 1005 * @param mode is the LFR mode to launch.
1001 1006 *
1002 1007 * The burst bits shall be before the enable bits.
1003 1008 *
1004 1009 */
1005 1010
1006 1011 // [0000 0000] burst f2, f1, f0 enable f3 f2 f1 f0
1007 1012 // the burst bits shall be set first, before the enable bits
1008 1013 switch(mode) {
1009 1014 case(LFR_MODE_NORMAL):
1010 1015 waveform_picker_regs->run_burst_enable = 0x00; // [0000 0000] no burst enable
1011 1016 waveform_picker_regs->run_burst_enable = 0x0f; // [0000 1111] enable f3 f2 f1 f0
1012 1017 break;
1013 1018 case(LFR_MODE_BURST):
1014 1019 waveform_picker_regs->run_burst_enable = 0x40; // [0100 0000] f2 burst enabled
1015 1020 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x04; // [0100] enable f2
1016 1021 break;
1017 1022 case(LFR_MODE_SBM1):
1018 1023 waveform_picker_regs->run_burst_enable = 0x20; // [0010 0000] f1 burst enabled
1019 1024 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0f; // [1111] enable f3 f2 f1 f0
1020 1025 break;
1021 1026 case(LFR_MODE_SBM2):
1022 1027 waveform_picker_regs->run_burst_enable = 0x40; // [0100 0000] f2 burst enabled
1023 1028 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0f; // [1111] enable f3 f2 f1 f0
1024 1029 break;
1025 1030 default:
1026 1031 waveform_picker_regs->run_burst_enable = 0x00; // [0000 0000] no burst enabled, no waveform enabled
1027 1032 break;
1028 1033 }
1029 1034 }
1030 1035 #else
1031 1036 void set_wfp_burst_enable_register( unsigned char mode )
1032 1037 {
1033 1038 /** This function sets the waveform picker burst_enable register depending on the mode.
1034 1039 *
1035 1040 * @param mode is the LFR mode to launch.
1036 1041 *
1037 1042 * The burst bits shall be before the enable bits.
1038 1043 *
1039 1044 */
1040 1045
1041 1046 // [0000 0000] burst f2, f1, f0 enable f3 f2 f1 f0
1042 1047 // the burst bits shall be set first, before the enable bits
1043 1048 switch(mode) {
1044 1049 case(LFR_MODE_NORMAL):
1045 1050 waveform_picker_regs->burst_enable = 0x00; // [0000 0000] no burst enable
1046 1051 waveform_picker_regs->burst_enable = 0x0f; // [0000 1111] enable f3 f2 f1 f0
1047 1052 break;
1048 1053 case(LFR_MODE_BURST):
1049 1054 waveform_picker_regs->burst_enable = 0x40; // [0100 0000] f2 burst enabled
1050 1055 waveform_picker_regs->burst_enable = waveform_picker_regs->burst_enable | 0x04; // [0100] enable f2
1051 1056 break;
1052 1057 case(LFR_MODE_SBM1):
1053 1058 waveform_picker_regs->burst_enable = 0x20; // [0010 0000] f1 burst enabled
1054 1059 waveform_picker_regs->burst_enable = waveform_picker_regs->burst_enable | 0x0f; // [1111] enable f3 f2 f1 f0
1055 1060 break;
1056 1061 case(LFR_MODE_SBM2):
1057 1062 waveform_picker_regs->burst_enable = 0x40; // [0100 0000] f2 burst enabled
1058 1063 waveform_picker_regs->burst_enable = waveform_picker_regs->burst_enable | 0x0f; // [1111] enable f3 f2 f1 f0
1059 1064 break;
1060 1065 default:
1061 1066 waveform_picker_regs->burst_enable = 0x00; // [0000 0000] no burst enabled, no waveform enabled
1062 1067 break;
1063 1068 }
1064 1069 }
1065 1070 #endif
1066 1071
1067 1072 void reset_wfp_burst_enable()
1068 1073 {
1069 1074 /** This function resets the waveform picker burst_enable register.
1070 1075 *
1071 1076 * The burst bits [f2 f1 f0] and the enable bits [f3 f2 f1 f0] are set to 0.
1072 1077 *
1073 1078 */
1074 1079
1075 1080 #ifdef VHDL_DEV
1076 1081 waveform_picker_regs->run_burst_enable = 0x00; // burst f2, f1, f0 enable f3, f2, f1, f0
1077 1082 #else
1078 1083 waveform_picker_regs->burst_enable = 0x00; // burst f2, f1, f0 enable f3, f2, f1, f0
1079 1084 #endif
1080 1085 }
1081 1086
1082 1087 void reset_wfp_status()
1083 1088 {
1084 1089 /** This function resets the waveform picker status register.
1085 1090 *
1086 1091 * All status bits are set to 0 [new_err full_err full].
1087 1092 *
1088 1093 */
1089 1094
1090 1095 #ifdef GSA
1091 1096 #else
1092 1097 waveform_picker_regs->status = 0x00; // burst f2, f1, f0 enable f3, f2, f1, f0
1093 1098 #endif
1094 1099 }
1095 1100
1096 1101 #ifdef VHDL_DEV
1097 1102 void reset_waveform_picker_regs()
1098 1103 {
1099 1104 /** This function resets the waveform picker module registers.
1100 1105 *
1101 1106 * The registers affected by this function are located at the following offset addresses:
1102 1107 * - 0x00 data_shaping
1103 1108 * - 0x04 run_burst_enable
1104 1109 * - 0x08 addr_data_f0
1105 1110 * - 0x0C addr_data_f1
1106 1111 * - 0x10 addr_data_f2
1107 1112 * - 0x14 addr_data_f3
1108 1113 * - 0x18 status
1109 1114 * - 0x1C delta_snapshot
1110 1115 * - 0x20 delta_f0
1111 1116 * - 0x24 delta_f0_2
1112 1117 * - 0x28 delta_f1
1113 1118 * - 0x2c delta_f2
1114 1119 * - 0x30 nb_data_by_buffer
1115 1120 * - 0x34 nb_snapshot_param
1116 1121 * - 0x38 start_date
1117 1122 * - 0x3c nb_word_in_buffer
1118 1123 *
1119 1124 */
1120 1125 waveform_picker_regs->data_shaping = 0x01; // 0x00 *** R1 R0 SP1 SP0 BW
1121 1126 waveform_picker_regs->run_burst_enable = 0x00; // 0x04 *** [run *** burst f2, f1, f0 *** enable f3, f2, f1, f0 ]
1122 1127 //waveform_picker_regs->addr_data_f0 = (int) (wf_snap_f0); // 0x08
1123 1128 waveform_picker_regs->addr_data_f0 = current_ring_node_f0->buffer_address; // 0x08
1124 1129 waveform_picker_regs->addr_data_f1 = current_ring_node_f1->buffer_address; // 0x0c
1125 1130 waveform_picker_regs->addr_data_f2 = current_ring_node_f2->buffer_address; // 0x10
1126 1131 waveform_picker_regs->addr_data_f3 = (int) (wf_cont_f3_a); // 0x14
1127 1132 waveform_picker_regs->status = 0x00; // 0x18
1128 1133 //
1129 // waveform_picker_regs->delta_snapshot = 0x1000; // 0x1c *** 4096 = 16 * 256
1130 // waveform_picker_regs->delta_f0 = 0xc0b; // 0x20 *** 3083 = 4096 - 1013
1131 // waveform_picker_regs->delta_f0_2 = 0x7; // 0x24 *** 7 [7 bits]
1132 // waveform_picker_regs->delta_f1 = 0xc40; // 0x28 *** 3136 = 4096 - 960
1133 // waveform_picker_regs->delta_f2 = 0xc00; // 0x2c *** 3072 = 12 * 256
1134 waveform_picker_regs->delta_snapshot = 0x1000; // 0x1c *** 4096 = 16 * 256
1135 waveform_picker_regs->delta_f0 = 0xc0b; // 0x20 *** 3083 = 4096 - 1013
1136 waveform_picker_regs->delta_f0_2 = 0x7; // 0x24 *** 7 [7 bits]
1137 waveform_picker_regs->delta_f1 = 0xc40; // 0x28 *** 3136 = 4096 - 960
1138 waveform_picker_regs->delta_f2 = 0xc00; // 0x2c *** 3072 = 12 * 256
1134 1139 //
1135 waveform_picker_regs->delta_snapshot = 0x1000; // 0x1c *** 4096 = 16 * 256
1136 waveform_picker_regs->delta_f0 = 0x1; // 0x20 ***
1137 waveform_picker_regs->delta_f0_2 = 0x7; // 0x24 *** 7 [7 bits]
1138 waveform_picker_regs->delta_f1 = 0x1; // 0x28 ***
1139 waveform_picker_regs->delta_f2 = 0x1; // 0x2c ***
1140 // waveform_picker_regs->delta_snapshot = 0x1000; // 0x1c *** 4096 = 16 * 256
1141 // waveform_picker_regs->delta_f0 = 0x1; // 0x20 ***
1142 // waveform_picker_regs->delta_f0_2 = 0x7; // 0x24 *** 7 [7 bits]
1143 // waveform_picker_regs->delta_f1 = 0x1; // 0x28 ***
1144 // waveform_picker_regs->delta_f2 = 0x1; // 0x2c ***
1145 //
1146 // waveform_picker_regs->delta_snapshot = 0x1000; // 0x1c *** 4096 = 16 * 256
1147 // waveform_picker_regs->delta_f0 = 0x0fff; // 0x20 ***
1148 // waveform_picker_regs->delta_f0_2 = 0x7; // 0x24 *** 7 [7 bits]
1149 // waveform_picker_regs->delta_f1 = 0x0fff; // 0x28 ***
1150 // waveform_picker_regs->delta_f2 = 0x1; // 0x2c ***
1140 1151 // 2048
1141 1152 // waveform_picker_regs->nb_data_by_buffer = 0x7ff; // 0x30 *** 2048 -1 => nb samples -1
1142 1153 // waveform_picker_regs->snapshot_param = 0x800; // 0x34 *** 2048 => nb samples
1143 1154 // waveform_picker_regs->start_date = 0x00; // 0x38
1144 1155 // waveform_picker_regs->nb_word_in_buffer = 0x1802; // 0x3c *** 2048 * 3 + 2 = 6146
1145 1156 // 2352 = 7 * 336
1146 1157 waveform_picker_regs->nb_data_by_buffer = 0x92f; // 0x30 *** 2352 - 1 => nb samples -1
1147 1158 waveform_picker_regs->snapshot_param = 0x930; // 0x34 *** 2352 => nb samples
1148 1159 waveform_picker_regs->start_date = 0x00; // 0x38
1149 1160 waveform_picker_regs->nb_word_in_buffer = 0x1b92; // 0x3c *** 2352 * 3 + 2 = 7058
1150 1161 }
1151 1162 #else
1152 1163 void reset_waveform_picker_regs()
1153 1164 {
1154 1165 /** This function resets the waveform picker module registers.
1155 1166 *
1156 1167 * The registers affected by this function are located at the following offset addresses:
1157 1168 * - 0x00 data_shaping
1158 1169 * - 0x04 burst_enable
1159 1170 * - 0x08 addr_data_f0
1160 1171 * - 0x0C addr_data_f1
1161 1172 * - 0x10 addr_data_f2
1162 1173 * - 0x14 addr_data_f3
1163 1174 * - 0x18 status
1164 1175 * - 0x1C delta_snapshot
1165 1176 * - 0x20 delta_f2_f1
1166 1177 * - 0x24 delta_f2_f0
1167 1178 * - 0x28 nb_burst
1168 1179 * - 0x2C nb_snapshot
1169 1180 *
1170 1181 */
1171 1182
1172 1183 reset_wfp_burst_enable();
1173 1184 reset_wfp_status();
1174 1185 // set buffer addresses
1175 1186 waveform_picker_regs->addr_data_f0 = (int) (wf_snap_f0);
1176 1187 waveform_picker_regs->addr_data_f1 = current_ring_node_f1->buffer_address;
1177 1188 waveform_picker_regs->addr_data_f2 = current_ring_node_f2->buffer_address;
1178 1189 waveform_picker_regs->addr_data_f3 = (int) (wf_cont_f3_a);
1179 1190 // set other parameters
1180 1191 set_wfp_data_shaping();
1181 1192 set_wfp_delta_snapshot(); // time in seconds between two snapshots
1182 1193 waveform_picker_regs->delta_f2_f1 = 0xffff; // 0x16800 => 92160 (max 4 bytes)
1183 1194 waveform_picker_regs->delta_f2_f0 = 0x17c00; // 97 280 (max 5 bytes)
1184 1195 // waveform_picker_regs->nb_burst_available = 0x180; // max 3 bytes, size of the buffer in burst (1 burst = 16 x 4 octets)
1185 1196 // // 3 * 2048 / 16 = 384
1186 1197 // waveform_picker_regs->nb_snapshot_param = 0x7ff; // max 3 octets, 2048 - 1
1187 1198 waveform_picker_regs->nb_burst_available = 0x1b9; // max 3 bytes, size of the buffer in burst (1 burst = 16 x 4 octets)
1188 1199 // 3 * 2352 / 16 = 441
1189 1200 waveform_picker_regs->nb_snapshot_param = 0x944; // max 3 octets, 2372 - 1
1190 1201 }
1191 1202 #endif
1192 1203
1193 1204 //*****************
1194 1205 // local parameters
1195 1206 void set_local_nb_interrupt_f0_MAX( void )
1196 1207 {
1197 1208 /** This function sets the value of the nb_interrupt_f0_MAX local parameter.
1198 1209 *
1199 1210 * This parameter is used for the SM validation only.\n
1200 1211 * The software waits param_local.local_nb_interrupt_f0_MAX interruptions from the spectral matrices
1201 1212 * module before launching a basic processing.
1202 1213 *
1203 1214 */
1204 1215
1205 1216 param_local.local_nb_interrupt_f0_MAX = ( (parameter_dump_packet.sy_lfr_n_asm_p[0]) * 256
1206 1217 + parameter_dump_packet.sy_lfr_n_asm_p[1] ) * 100;
1207 1218 }
1208 1219
1209 1220 void increment_seq_counter_source_id( unsigned char *packet_sequence_control, unsigned int sid )
1210 1221 {
1211 1222 unsigned short *sequence_cnt;
1212 1223 unsigned short segmentation_grouping_flag;
1213 1224 unsigned short new_packet_sequence_control;
1214 1225
1215 1226 if ( (sid ==SID_NORM_SWF_F0) || (sid ==SID_NORM_SWF_F1) || (sid ==SID_NORM_SWF_F2)
1216 1227 || (sid ==SID_NORM_CWF_F3) || (sid==SID_NORM_CWF_LONG_F3) || (sid ==SID_BURST_CWF_F2) )
1217 1228 {
1218 1229 sequence_cnt = &sequenceCounters_SCIENCE_NORMAL_BURST;
1219 1230 }
1220 1231 else if ( (sid ==SID_SBM1_CWF_F1) || (sid ==SID_SBM2_CWF_F2) )
1221 1232 {
1222 1233 sequence_cnt = &sequenceCounters_SCIENCE_SBM1_SBM2;
1223 1234 }
1224 1235 else
1225 1236 {
1226 1237 sequence_cnt = NULL;
1227 1238 PRINTF1("in increment_seq_counter_source_id *** ERR apid_destid %d not known\n", sid)
1228 1239 }
1229 1240
1230 1241 if (sequence_cnt != NULL)
1231 1242 {
1232 1243 segmentation_grouping_flag = (packet_sequence_control[ 0 ] & 0xc0) << 8;
1233 1244 *sequence_cnt = (*sequence_cnt) & 0x3fff;
1234 1245
1235 1246 new_packet_sequence_control = segmentation_grouping_flag | *sequence_cnt ;
1236 1247
1237 1248 packet_sequence_control[0] = (unsigned char) (new_packet_sequence_control >> 8);
1238 1249 packet_sequence_control[1] = (unsigned char) (new_packet_sequence_control );
1239 1250
1240 1251 // increment the sequence counter for the next packet
1241 1252 if ( *sequence_cnt < SEQ_CNT_MAX)
1242 1253 {
1243 1254 *sequence_cnt = *sequence_cnt + 1;
1244 1255 }
1245 1256 else
1246 1257 {
1247 1258 *sequence_cnt = 0;
1248 1259 }
1249 1260 }
1250 1261 }
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now