##// END OF EJS Templates
modifications following 634:...
paul -
r279:42c0a3b87048 R3a
parent child
Show More
@@ -1,2 +1,2
1 3081d1f9bb20b2b64a192585337a292a9804e0c5 LFR_basic-parameters
1 3081d1f9bb20b2b64a192585337a292a9804e0c5 LFR_basic-parameters
2 449d1ebc41af2e62571508883dab8043a33f16df header/lfr_common_headers
2 1f3d7ce688e982a378d739596c8e3f8972f40b9d header/lfr_common_headers
@@ -1,58 +1,59
1 #ifndef FSW_SPACEWIRE_H_INCLUDED
1 #ifndef FSW_SPACEWIRE_H_INCLUDED
2 #define FSW_SPACEWIRE_H_INCLUDED
2 #define FSW_SPACEWIRE_H_INCLUDED
3
3
4 #include <rtems.h>
4 #include <rtems.h>
5 #include <grspw.h>
5 #include <grspw.h>
6
6
7 #include <fcntl.h> // for O_RDWR
7 #include <fcntl.h> // for O_RDWR
8 #include <unistd.h> // for the read call
8 #include <unistd.h> // for the read call
9 #include <sys/ioctl.h> // for the ioctl call
9 #include <sys/ioctl.h> // for the ioctl call
10 #include <errno.h>
10 #include <errno.h>
11
11
12 #include "fsw_params.h"
12 #include "fsw_params.h"
13 #include "tc_handler.h"
13 #include "tc_handler.h"
14 #include "fsw_init.h"
14 #include "fsw_init.h"
15
15
16 extern spw_stats grspw_stats;
16 extern spw_stats grspw_stats;
17 extern rtems_name timecode_timer_name;
17 extern rtems_name timecode_timer_name;
18 extern rtems_id timecode_timer_id;
18 extern rtems_id timecode_timer_id;
19 extern unsigned char oneTcLfrUpdateTimeReceived;
19 extern unsigned char oneTcLfrUpdateTimeReceived;
20
20
21 // RTEMS TASK
21 // RTEMS TASK
22 rtems_task spiq_task( rtems_task_argument argument );
22 rtems_task spiq_task( rtems_task_argument argument );
23 rtems_task recv_task( rtems_task_argument unused );
23 rtems_task recv_task( rtems_task_argument unused );
24 rtems_task send_task( rtems_task_argument argument );
24 rtems_task send_task( rtems_task_argument argument );
25 rtems_task link_task( rtems_task_argument argument );
25 rtems_task link_task( rtems_task_argument argument );
26
26
27 int spacewire_open_link( void );
27 int spacewire_open_link( void );
28 int spacewire_start_link( int fd );
28 int spacewire_start_link( int fd );
29 int spacewire_stop_and_start_link( int fd );
29 int spacewire_stop_and_start_link( int fd );
30 int spacewire_configure_link(int fd );
30 int spacewire_configure_link(int fd );
31 int spacewire_several_connect_attemps( void );
31 int spacewire_several_connect_attemps( void );
32 void spacewire_set_NP( unsigned char val, unsigned int regAddr ); // No Port force
32 void spacewire_set_NP( unsigned char val, unsigned int regAddr ); // No Port force
33 void spacewire_set_RE( unsigned char val, unsigned int regAddr ); // RMAP Enable
33 void spacewire_set_RE( unsigned char val, unsigned int regAddr ); // RMAP Enable
34 void spacewire_read_statistics( void );
34 void spacewire_read_statistics( void );
35 void spacewire_get_last_error( void );
35 void spacewire_get_last_error( void );
36 void update_hk_lfr_last_er_fields(unsigned int rid, unsigned char code);
36 void update_hk_lfr_last_er_fields(unsigned int rid, unsigned char code);
37 void update_hk_with_grspw_stats(void );
37 void update_hk_with_grspw_stats(void );
38 void spacewire_update_hk_lfr_link_state( unsigned char *hk_lfr_status_word_0 );
38 void increase_unsigned_char_counter( unsigned char *counter );
39 void increase_unsigned_char_counter( unsigned char *counter );
39
40
40 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header );
41 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header );
41 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header );
42 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header );
42 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header );
43 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header );
43 int spw_send_waveform_CWF( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_CWF_t *header );
44 int spw_send_waveform_CWF( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_CWF_t *header );
44 int spw_send_waveform_SWF( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_SWF_t *header );
45 int spw_send_waveform_SWF( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_SWF_t *header );
45 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_CWF_t *header );
46 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_CWF_t *header );
46 void spw_send_asm_f0( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
47 void spw_send_asm_f0( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
47 void spw_send_asm_f1( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
48 void spw_send_asm_f1( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
48 void spw_send_asm_f2( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
49 void spw_send_asm_f2( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
49 void spw_send_k_dump( ring_node *ring_node_to_send );
50 void spw_send_k_dump( ring_node *ring_node_to_send );
50
51
51 unsigned int check_timecode_and_previous_timecode_coherency(unsigned char currentTimecodeCtr);
52 unsigned int check_timecode_and_previous_timecode_coherency(unsigned char currentTimecodeCtr);
52 unsigned int check_timecode_and_internal_time_coherency(unsigned char timecode, unsigned char internalTime);
53 unsigned int check_timecode_and_internal_time_coherency(unsigned char timecode, unsigned char internalTime);
53 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc );
54 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc );
54 rtems_timer_service_routine timecode_timer_routine( rtems_id timer_id, void *user_data );
55 rtems_timer_service_routine timecode_timer_routine( rtems_id timer_id, void *user_data );
55
56
56 void (*grspw_timecode_callback) ( void *pDev, void *regs, int minor, unsigned int tc );
57 void (*grspw_timecode_callback) ( void *pDev, void *regs, int minor, unsigned int tc );
57
58
58 #endif // FSW_SPACEWIRE_H_INCLUDED
59 #endif // FSW_SPACEWIRE_H_INCLUDED
@@ -1,797 +1,802
1 /** General usage functions and RTEMS tasks.
1 /** General usage functions and RTEMS tasks.
2 *
2 *
3 * @file
3 * @file
4 * @author P. LEROY
4 * @author P. LEROY
5 *
5 *
6 */
6 */
7
7
8 #include "fsw_misc.h"
8 #include "fsw_misc.h"
9
9
10 void timer_configure(unsigned char timer, unsigned int clock_divider,
10 void timer_configure(unsigned char timer, unsigned int clock_divider,
11 unsigned char interrupt_level, rtems_isr (*timer_isr)() )
11 unsigned char interrupt_level, rtems_isr (*timer_isr)() )
12 {
12 {
13 /** This function configures a GPTIMER timer instantiated in the VHDL design.
13 /** This function configures a GPTIMER timer instantiated in the VHDL design.
14 *
14 *
15 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
15 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
16 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
16 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
17 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
17 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
18 * @param interrupt_level is the interrupt level that the timer drives.
18 * @param interrupt_level is the interrupt level that the timer drives.
19 * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer.
19 * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer.
20 *
20 *
21 * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76
21 * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76
22 *
22 *
23 */
23 */
24
24
25 rtems_status_code status;
25 rtems_status_code status;
26 rtems_isr_entry old_isr_handler;
26 rtems_isr_entry old_isr_handler;
27
27
28 gptimer_regs->timer[timer].ctrl = 0x00; // reset the control register
28 gptimer_regs->timer[timer].ctrl = 0x00; // reset the control register
29
29
30 status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels
30 status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels
31 if (status!=RTEMS_SUCCESSFUL)
31 if (status!=RTEMS_SUCCESSFUL)
32 {
32 {
33 PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n")
33 PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n")
34 }
34 }
35
35
36 timer_set_clock_divider( timer, clock_divider);
36 timer_set_clock_divider( timer, clock_divider);
37 }
37 }
38
38
39 void timer_start(unsigned char timer)
39 void timer_start(unsigned char timer)
40 {
40 {
41 /** This function starts a GPTIMER timer.
41 /** This function starts a GPTIMER timer.
42 *
42 *
43 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
43 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
44 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
44 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
45 *
45 *
46 */
46 */
47
47
48 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
48 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
49 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000004; // LD load value from the reload register
49 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000004; // LD load value from the reload register
50 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000001; // EN enable the timer
50 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000001; // EN enable the timer
51 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000002; // RS restart
51 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000002; // RS restart
52 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000008; // IE interrupt enable
52 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000008; // IE interrupt enable
53 }
53 }
54
54
55 void timer_stop(unsigned char timer)
55 void timer_stop(unsigned char timer)
56 {
56 {
57 /** This function stops a GPTIMER timer.
57 /** This function stops a GPTIMER timer.
58 *
58 *
59 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
59 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
60 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
60 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
61 *
61 *
62 */
62 */
63
63
64 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xfffffffe; // EN enable the timer
64 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xfffffffe; // EN enable the timer
65 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xffffffef; // IE interrupt enable
65 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xffffffef; // IE interrupt enable
66 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
66 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
67 }
67 }
68
68
69 void timer_set_clock_divider(unsigned char timer, unsigned int clock_divider)
69 void timer_set_clock_divider(unsigned char timer, unsigned int clock_divider)
70 {
70 {
71 /** This function sets the clock divider of a GPTIMER timer.
71 /** This function sets the clock divider of a GPTIMER timer.
72 *
72 *
73 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
73 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
74 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
74 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
75 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
75 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
76 *
76 *
77 */
77 */
78
78
79 gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz
79 gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz
80 }
80 }
81
81
82 // WATCHDOG
82 // WATCHDOG
83
83
84 rtems_isr watchdog_isr( rtems_vector_number vector )
84 rtems_isr watchdog_isr( rtems_vector_number vector )
85 {
85 {
86 rtems_status_code status_code;
86 rtems_status_code status_code;
87
87
88 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_12 );
88 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_12 );
89
89
90 PRINTF("watchdog_isr *** this is the end, exit(0)\n");
90 PRINTF("watchdog_isr *** this is the end, exit(0)\n");
91
91
92 exit(0);
92 exit(0);
93 }
93 }
94
94
95 void watchdog_configure(void)
95 void watchdog_configure(void)
96 {
96 {
97 /** This function configure the watchdog.
97 /** This function configure the watchdog.
98 *
98 *
99 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
99 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
100 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
100 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
101 *
101 *
102 * The watchdog is a timer provided by the GPTIMER IP core of the GRLIB.
102 * The watchdog is a timer provided by the GPTIMER IP core of the GRLIB.
103 *
103 *
104 */
104 */
105
105
106 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt during configuration
106 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt during configuration
107
107
108 timer_configure( TIMER_WATCHDOG, CLKDIV_WATCHDOG, IRQ_SPARC_GPTIMER_WATCHDOG, watchdog_isr );
108 timer_configure( TIMER_WATCHDOG, CLKDIV_WATCHDOG, IRQ_SPARC_GPTIMER_WATCHDOG, watchdog_isr );
109
109
110 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
110 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
111 }
111 }
112
112
113 void watchdog_stop(void)
113 void watchdog_stop(void)
114 {
114 {
115 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt line
115 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt line
116 timer_stop( TIMER_WATCHDOG );
116 timer_stop( TIMER_WATCHDOG );
117 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
117 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
118 }
118 }
119
119
120 void watchdog_reload(void)
120 void watchdog_reload(void)
121 {
121 {
122 /** This function reloads the watchdog timer counter with the timer reload value.
122 /** This function reloads the watchdog timer counter with the timer reload value.
123 *
123 *
124 * @param void
124 * @param void
125 *
125 *
126 * @return void
126 * @return void
127 *
127 *
128 */
128 */
129
129
130 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
130 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
131 }
131 }
132
132
133 void watchdog_start(void)
133 void watchdog_start(void)
134 {
134 {
135 /** This function starts the watchdog timer.
135 /** This function starts the watchdog timer.
136 *
136 *
137 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
137 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
138 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
138 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
139 *
139 *
140 */
140 */
141
141
142 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG );
142 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG );
143
143
144 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000010; // clear pending IRQ if any
144 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000010; // clear pending IRQ if any
145 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
145 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
146 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000001; // EN enable the timer
146 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000001; // EN enable the timer
147 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000008; // IE interrupt enable
147 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000008; // IE interrupt enable
148
148
149 LEON_Unmask_interrupt( IRQ_GPTIMER_WATCHDOG );
149 LEON_Unmask_interrupt( IRQ_GPTIMER_WATCHDOG );
150
150
151 }
151 }
152
152
153 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
153 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
154 {
154 {
155 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
155 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
156
156
157 apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE;
157 apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE;
158
158
159 return 0;
159 return 0;
160 }
160 }
161
161
162 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
162 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
163 {
163 {
164 /** This function sets the scaler reload register of the apbuart module
164 /** This function sets the scaler reload register of the apbuart module
165 *
165 *
166 * @param regs is the address of the apbuart registers in memory
166 * @param regs is the address of the apbuart registers in memory
167 * @param value is the value that will be stored in the scaler register
167 * @param value is the value that will be stored in the scaler register
168 *
168 *
169 * The value shall be set by the software to get data on the serial interface.
169 * The value shall be set by the software to get data on the serial interface.
170 *
170 *
171 */
171 */
172
172
173 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
173 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
174
174
175 apbuart_regs->scaler = value;
175 apbuart_regs->scaler = value;
176
176
177 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
177 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
178 }
178 }
179
179
180 //************
180 //************
181 // RTEMS TASKS
181 // RTEMS TASKS
182
182
183 rtems_task load_task(rtems_task_argument argument)
183 rtems_task load_task(rtems_task_argument argument)
184 {
184 {
185 BOOT_PRINTF("in LOAD *** \n")
185 BOOT_PRINTF("in LOAD *** \n")
186
186
187 rtems_status_code status;
187 rtems_status_code status;
188 unsigned int i;
188 unsigned int i;
189 unsigned int j;
189 unsigned int j;
190 rtems_name name_watchdog_rate_monotonic; // name of the watchdog rate monotonic
190 rtems_name name_watchdog_rate_monotonic; // name of the watchdog rate monotonic
191 rtems_id watchdog_period_id; // id of the watchdog rate monotonic period
191 rtems_id watchdog_period_id; // id of the watchdog rate monotonic period
192
192
193 name_watchdog_rate_monotonic = rtems_build_name( 'L', 'O', 'A', 'D' );
193 name_watchdog_rate_monotonic = rtems_build_name( 'L', 'O', 'A', 'D' );
194
194
195 status = rtems_rate_monotonic_create( name_watchdog_rate_monotonic, &watchdog_period_id );
195 status = rtems_rate_monotonic_create( name_watchdog_rate_monotonic, &watchdog_period_id );
196 if( status != RTEMS_SUCCESSFUL ) {
196 if( status != RTEMS_SUCCESSFUL ) {
197 PRINTF1( "in LOAD *** rtems_rate_monotonic_create failed with status of %d\n", status )
197 PRINTF1( "in LOAD *** rtems_rate_monotonic_create failed with status of %d\n", status )
198 }
198 }
199
199
200 i = 0;
200 i = 0;
201 j = 0;
201 j = 0;
202
202
203 watchdog_configure();
203 watchdog_configure();
204
204
205 watchdog_start();
205 watchdog_start();
206
206
207 set_sy_lfr_watchdog_enabled( true );
207 set_sy_lfr_watchdog_enabled( true );
208
208
209 while(1){
209 while(1){
210 status = rtems_rate_monotonic_period( watchdog_period_id, WATCHDOG_PERIOD );
210 status = rtems_rate_monotonic_period( watchdog_period_id, WATCHDOG_PERIOD );
211 watchdog_reload();
211 watchdog_reload();
212 i = i + 1;
212 i = i + 1;
213 if ( i == 10 )
213 if ( i == 10 )
214 {
214 {
215 i = 0;
215 i = 0;
216 j = j + 1;
216 j = j + 1;
217 PRINTF1("%d\n", j)
217 PRINTF1("%d\n", j)
218 }
218 }
219 #ifdef DEBUG_WATCHDOG
219 #ifdef DEBUG_WATCHDOG
220 if (j == 3 )
220 if (j == 3 )
221 {
221 {
222 status = rtems_task_delete(RTEMS_SELF);
222 status = rtems_task_delete(RTEMS_SELF);
223 }
223 }
224 #endif
224 #endif
225 }
225 }
226 }
226 }
227
227
228 rtems_task hous_task(rtems_task_argument argument)
228 rtems_task hous_task(rtems_task_argument argument)
229 {
229 {
230 rtems_status_code status;
230 rtems_status_code status;
231 rtems_status_code spare_status;
231 rtems_status_code spare_status;
232 rtems_id queue_id;
232 rtems_id queue_id;
233 rtems_rate_monotonic_period_status period_status;
233 rtems_rate_monotonic_period_status period_status;
234
234
235 status = get_message_queue_id_send( &queue_id );
235 status = get_message_queue_id_send( &queue_id );
236 if (status != RTEMS_SUCCESSFUL)
236 if (status != RTEMS_SUCCESSFUL)
237 {
237 {
238 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
238 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
239 }
239 }
240
240
241 BOOT_PRINTF("in HOUS ***\n");
241 BOOT_PRINTF("in HOUS ***\n");
242
242
243 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
243 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
244 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
244 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
245 if( status != RTEMS_SUCCESSFUL ) {
245 if( status != RTEMS_SUCCESSFUL ) {
246 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status );
246 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status );
247 }
247 }
248 }
248 }
249
249
250 status = rtems_rate_monotonic_cancel(HK_id);
250 status = rtems_rate_monotonic_cancel(HK_id);
251 if( status != RTEMS_SUCCESSFUL ) {
251 if( status != RTEMS_SUCCESSFUL ) {
252 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status );
252 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status );
253 }
253 }
254 else {
254 else {
255 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n");
255 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n");
256 }
256 }
257
257
258 // startup phase
258 // startup phase
259 status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks );
259 status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks );
260 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
260 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
261 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
261 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
262 while(period_status.state != RATE_MONOTONIC_EXPIRED ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway
262 while(period_status.state != RATE_MONOTONIC_EXPIRED ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway
263 {
263 {
264 if ((time_management_regs->coarse_time & 0x80000000) == 0x00000000) // check time synchronization
264 if ((time_management_regs->coarse_time & 0x80000000) == 0x00000000) // check time synchronization
265 {
265 {
266 break; // break if LFR is synchronized
266 break; // break if LFR is synchronized
267 }
267 }
268 else
268 else
269 {
269 {
270 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
270 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
271 // sched_yield();
271 // sched_yield();
272 status = rtems_task_wake_after( 10 ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 100 ms = 10 * 10 ms
272 status = rtems_task_wake_after( 10 ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 100 ms = 10 * 10 ms
273 }
273 }
274 }
274 }
275 status = rtems_rate_monotonic_cancel(HK_id);
275 status = rtems_rate_monotonic_cancel(HK_id);
276 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
276 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
277
277
278 set_hk_lfr_reset_cause( POWER_ON );
278 set_hk_lfr_reset_cause( UNKNOWN_CAUSE );
279
279
280 while(1){ // launch the rate monotonic task
280 while(1){ // launch the rate monotonic task
281 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
281 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
282 if ( status != RTEMS_SUCCESSFUL ) {
282 if ( status != RTEMS_SUCCESSFUL ) {
283 PRINTF1( "in HOUS *** ERR period: %d\n", status);
283 PRINTF1( "in HOUS *** ERR period: %d\n", status);
284 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
284 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
285 }
285 }
286 else {
286 else {
287 housekeeping_packet.packetSequenceControl[0] = (unsigned char) (sequenceCounterHK >> 8);
287 housekeeping_packet.packetSequenceControl[0] = (unsigned char) (sequenceCounterHK >> 8);
288 housekeeping_packet.packetSequenceControl[1] = (unsigned char) (sequenceCounterHK );
288 housekeeping_packet.packetSequenceControl[1] = (unsigned char) (sequenceCounterHK );
289 increment_seq_counter( &sequenceCounterHK );
289 increment_seq_counter( &sequenceCounterHK );
290
290
291 housekeeping_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
291 housekeeping_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
292 housekeeping_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
292 housekeeping_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
293 housekeeping_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
293 housekeeping_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
294 housekeeping_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
294 housekeeping_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
295 housekeeping_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
295 housekeeping_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
296 housekeeping_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
296 housekeeping_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
297
297
298 spacewire_update_hk_lfr_link_state( &housekeeping_packet.lfr_status_word[0] );
299
298 spacewire_read_statistics();
300 spacewire_read_statistics();
299
301
300 update_hk_with_grspw_stats();
302 update_hk_with_grspw_stats();
301
303
302 set_hk_lfr_time_not_synchro();
304 set_hk_lfr_time_not_synchro();
303
305
304 housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max;
306 housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max;
305 housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max;
307 housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max;
306 housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max;
308 housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max;
307 housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max;
309 housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max;
308 housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max;
310 housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max;
309
311
310 housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare;
312 housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare;
311 housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
313 housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
312 get_temperatures( housekeeping_packet.hk_lfr_temp_scm );
314 get_temperatures( housekeeping_packet.hk_lfr_temp_scm );
313 get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 );
315 get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 );
314 get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load );
316 get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load );
315
317
316 hk_lfr_le_me_he_update();
318 hk_lfr_le_me_he_update();
317
319
318 // SEND PACKET
320 // SEND PACKET
319 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
321 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
320 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
322 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
321 if (status != RTEMS_SUCCESSFUL) {
323 if (status != RTEMS_SUCCESSFUL) {
322 PRINTF1("in HOUS *** ERR send: %d\n", status)
324 PRINTF1("in HOUS *** ERR send: %d\n", status)
323 }
325 }
324 }
326 }
325 }
327 }
326
328
327 PRINTF("in HOUS *** deleting task\n")
329 PRINTF("in HOUS *** deleting task\n")
328
330
329 status = rtems_task_delete( RTEMS_SELF ); // should not return
331 status = rtems_task_delete( RTEMS_SELF ); // should not return
330
332
331 return;
333 return;
332 }
334 }
333
335
334 rtems_task dumb_task( rtems_task_argument unused )
336 rtems_task dumb_task( rtems_task_argument unused )
335 {
337 {
336 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
338 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
337 *
339 *
338 * @param unused is the starting argument of the RTEMS task
340 * @param unused is the starting argument of the RTEMS task
339 *
341 *
340 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
342 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
341 *
343 *
342 */
344 */
343
345
344 unsigned int i;
346 unsigned int i;
345 unsigned int intEventOut;
347 unsigned int intEventOut;
346 unsigned int coarse_time = 0;
348 unsigned int coarse_time = 0;
347 unsigned int fine_time = 0;
349 unsigned int fine_time = 0;
348 rtems_event_set event_out;
350 rtems_event_set event_out;
349
351
350 char *DumbMessages[15] = {"in DUMB *** default", // RTEMS_EVENT_0
352 char *DumbMessages[15] = {"in DUMB *** default", // RTEMS_EVENT_0
351 "in DUMB *** timecode_irq_handler", // RTEMS_EVENT_1
353 "in DUMB *** timecode_irq_handler", // RTEMS_EVENT_1
352 "in DUMB *** f3 buffer changed", // RTEMS_EVENT_2
354 "in DUMB *** f3 buffer changed", // RTEMS_EVENT_2
353 "in DUMB *** in SMIQ *** Error sending event to AVF0", // RTEMS_EVENT_3
355 "in DUMB *** in SMIQ *** Error sending event to AVF0", // RTEMS_EVENT_3
354 "in DUMB *** spectral_matrices_isr *** Error sending event to SMIQ", // RTEMS_EVENT_4
356 "in DUMB *** spectral_matrices_isr *** Error sending event to SMIQ", // RTEMS_EVENT_4
355 "in DUMB *** waveforms_simulator_isr", // RTEMS_EVENT_5
357 "in DUMB *** waveforms_simulator_isr", // RTEMS_EVENT_5
356 "VHDL SM *** two buffers f0 ready", // RTEMS_EVENT_6
358 "VHDL SM *** two buffers f0 ready", // RTEMS_EVENT_6
357 "ready for dump", // RTEMS_EVENT_7
359 "ready for dump", // RTEMS_EVENT_7
358 "VHDL ERR *** spectral matrix", // RTEMS_EVENT_8
360 "VHDL ERR *** spectral matrix", // RTEMS_EVENT_8
359 "tick", // RTEMS_EVENT_9
361 "tick", // RTEMS_EVENT_9
360 "VHDL ERR *** waveform picker", // RTEMS_EVENT_10
362 "VHDL ERR *** waveform picker", // RTEMS_EVENT_10
361 "VHDL ERR *** unexpected ready matrix values", // RTEMS_EVENT_11
363 "VHDL ERR *** unexpected ready matrix values", // RTEMS_EVENT_11
362 "WATCHDOG timer", // RTEMS_EVENT_12
364 "WATCHDOG timer", // RTEMS_EVENT_12
363 "TIMECODE timer", // RTEMS_EVENT_13
365 "TIMECODE timer", // RTEMS_EVENT_13
364 "TIMECODE ISR" // RTEMS_EVENT_14
366 "TIMECODE ISR" // RTEMS_EVENT_14
365 };
367 };
366
368
367 BOOT_PRINTF("in DUMB *** \n")
369 BOOT_PRINTF("in DUMB *** \n")
368
370
369 while(1){
371 while(1){
370 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
372 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
371 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7
373 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7
372 | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12 | RTEMS_EVENT_13
374 | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12 | RTEMS_EVENT_13
373 | RTEMS_EVENT_14,
375 | RTEMS_EVENT_14,
374 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
376 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
375 intEventOut = (unsigned int) event_out;
377 intEventOut = (unsigned int) event_out;
376 for ( i=0; i<32; i++)
378 for ( i=0; i<32; i++)
377 {
379 {
378 if ( ((intEventOut >> i) & 0x0001) != 0)
380 if ( ((intEventOut >> i) & 0x0001) != 0)
379 {
381 {
380 coarse_time = time_management_regs->coarse_time;
382 coarse_time = time_management_regs->coarse_time;
381 fine_time = time_management_regs->fine_time;
383 fine_time = time_management_regs->fine_time;
382 if (i==12)
384 if (i==12)
383 {
385 {
384 PRINTF1("%s\n", DumbMessages[12])
386 PRINTF1("%s\n", DumbMessages[12])
385 }
387 }
386 if (i==13)
388 if (i==13)
387 {
389 {
388 PRINTF1("%s\n", DumbMessages[13])
390 PRINTF1("%s\n", DumbMessages[13])
389 }
391 }
390 if (i==14)
392 if (i==14)
391 {
393 {
392 PRINTF1("%s\n", DumbMessages[1])
394 PRINTF1("%s\n", DumbMessages[1])
393 }
395 }
394 }
396 }
395 }
397 }
396 }
398 }
397 }
399 }
398
400
399 //*****************************
401 //*****************************
400 // init housekeeping parameters
402 // init housekeeping parameters
401
403
402 void init_housekeeping_parameters( void )
404 void init_housekeeping_parameters( void )
403 {
405 {
404 /** This function initialize the housekeeping_packet global variable with default values.
406 /** This function initialize the housekeeping_packet global variable with default values.
405 *
407 *
406 */
408 */
407
409
408 unsigned int i = 0;
410 unsigned int i = 0;
409 unsigned char *parameters;
411 unsigned char *parameters;
410 unsigned char sizeOfHK;
412 unsigned char sizeOfHK;
411
413
412 sizeOfHK = sizeof( Packet_TM_LFR_HK_t );
414 sizeOfHK = sizeof( Packet_TM_LFR_HK_t );
413
415
414 parameters = (unsigned char*) &housekeeping_packet;
416 parameters = (unsigned char*) &housekeeping_packet;
415
417
416 for(i = 0; i< sizeOfHK; i++)
418 for(i = 0; i< sizeOfHK; i++)
417 {
419 {
418 parameters[i] = 0x00;
420 parameters[i] = 0x00;
419 }
421 }
420
422
421 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
423 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
422 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
424 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
423 housekeeping_packet.reserved = DEFAULT_RESERVED;
425 housekeeping_packet.reserved = DEFAULT_RESERVED;
424 housekeeping_packet.userApplication = CCSDS_USER_APP;
426 housekeeping_packet.userApplication = CCSDS_USER_APP;
425 housekeeping_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
427 housekeeping_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
426 housekeeping_packet.packetID[1] = (unsigned char) (APID_TM_HK);
428 housekeeping_packet.packetID[1] = (unsigned char) (APID_TM_HK);
427 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
429 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
428 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
430 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
429 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
431 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
430 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
432 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
431 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
433 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
432 housekeeping_packet.serviceType = TM_TYPE_HK;
434 housekeeping_packet.serviceType = TM_TYPE_HK;
433 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
435 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
434 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
436 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
435 housekeeping_packet.sid = SID_HK;
437 housekeeping_packet.sid = SID_HK;
436
438
437 // init status word
439 // init status word
438 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
440 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
439 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
441 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
440 // init software version
442 // init software version
441 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
443 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
442 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
444 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
443 housekeeping_packet.lfr_sw_version[2] = SW_VERSION_N3;
445 housekeeping_packet.lfr_sw_version[2] = SW_VERSION_N3;
444 housekeeping_packet.lfr_sw_version[3] = SW_VERSION_N4;
446 housekeeping_packet.lfr_sw_version[3] = SW_VERSION_N4;
445 // init fpga version
447 // init fpga version
446 parameters = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
448 parameters = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
447 housekeeping_packet.lfr_fpga_version[0] = parameters[1]; // n1
449 housekeeping_packet.lfr_fpga_version[0] = parameters[1]; // n1
448 housekeeping_packet.lfr_fpga_version[1] = parameters[2]; // n2
450 housekeeping_packet.lfr_fpga_version[1] = parameters[2]; // n2
449 housekeeping_packet.lfr_fpga_version[2] = parameters[3]; // n3
451 housekeeping_packet.lfr_fpga_version[2] = parameters[3]; // n3
450
452
451 housekeeping_packet.hk_lfr_q_sd_fifo_size = MSG_QUEUE_COUNT_SEND;
453 housekeeping_packet.hk_lfr_q_sd_fifo_size = MSG_QUEUE_COUNT_SEND;
452 housekeeping_packet.hk_lfr_q_rv_fifo_size = MSG_QUEUE_COUNT_RECV;
454 housekeeping_packet.hk_lfr_q_rv_fifo_size = MSG_QUEUE_COUNT_RECV;
453 housekeeping_packet.hk_lfr_q_p0_fifo_size = MSG_QUEUE_COUNT_PRC0;
455 housekeeping_packet.hk_lfr_q_p0_fifo_size = MSG_QUEUE_COUNT_PRC0;
454 housekeeping_packet.hk_lfr_q_p1_fifo_size = MSG_QUEUE_COUNT_PRC1;
456 housekeeping_packet.hk_lfr_q_p1_fifo_size = MSG_QUEUE_COUNT_PRC1;
455 housekeeping_packet.hk_lfr_q_p2_fifo_size = MSG_QUEUE_COUNT_PRC2;
457 housekeeping_packet.hk_lfr_q_p2_fifo_size = MSG_QUEUE_COUNT_PRC2;
456 }
458 }
457
459
458 void increment_seq_counter( unsigned short *packetSequenceControl )
460 void increment_seq_counter( unsigned short *packetSequenceControl )
459 {
461 {
460 /** This function increment the sequence counter passes in argument.
462 /** This function increment the sequence counter passes in argument.
461 *
463 *
462 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
464 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
463 *
465 *
464 */
466 */
465
467
466 unsigned short segmentation_grouping_flag;
468 unsigned short segmentation_grouping_flag;
467 unsigned short sequence_cnt;
469 unsigned short sequence_cnt;
468
470
469 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8; // keep bits 7 downto 6
471 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8; // keep bits 7 downto 6
470 sequence_cnt = (*packetSequenceControl) & 0x3fff; // [0011 1111 1111 1111]
472 sequence_cnt = (*packetSequenceControl) & 0x3fff; // [0011 1111 1111 1111]
471
473
472 if ( sequence_cnt < SEQ_CNT_MAX)
474 if ( sequence_cnt < SEQ_CNT_MAX)
473 {
475 {
474 sequence_cnt = sequence_cnt + 1;
476 sequence_cnt = sequence_cnt + 1;
475 }
477 }
476 else
478 else
477 {
479 {
478 sequence_cnt = 0;
480 sequence_cnt = 0;
479 }
481 }
480
482
481 *packetSequenceControl = segmentation_grouping_flag | sequence_cnt ;
483 *packetSequenceControl = segmentation_grouping_flag | sequence_cnt ;
482 }
484 }
483
485
484 void getTime( unsigned char *time)
486 void getTime( unsigned char *time)
485 {
487 {
486 /** This function write the current local time in the time buffer passed in argument.
488 /** This function write the current local time in the time buffer passed in argument.
487 *
489 *
488 */
490 */
489
491
490 time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
492 time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
491 time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
493 time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
492 time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
494 time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
493 time[3] = (unsigned char) (time_management_regs->coarse_time);
495 time[3] = (unsigned char) (time_management_regs->coarse_time);
494 time[4] = (unsigned char) (time_management_regs->fine_time>>8);
496 time[4] = (unsigned char) (time_management_regs->fine_time>>8);
495 time[5] = (unsigned char) (time_management_regs->fine_time);
497 time[5] = (unsigned char) (time_management_regs->fine_time);
496 }
498 }
497
499
498 unsigned long long int getTimeAsUnsignedLongLongInt( )
500 unsigned long long int getTimeAsUnsignedLongLongInt( )
499 {
501 {
500 /** This function write the current local time in the time buffer passed in argument.
502 /** This function write the current local time in the time buffer passed in argument.
501 *
503 *
502 */
504 */
503 unsigned long long int time;
505 unsigned long long int time;
504
506
505 time = ( (unsigned long long int) (time_management_regs->coarse_time & 0x7fffffff) << 16 )
507 time = ( (unsigned long long int) (time_management_regs->coarse_time & 0x7fffffff) << 16 )
506 + time_management_regs->fine_time;
508 + time_management_regs->fine_time;
507
509
508 return time;
510 return time;
509 }
511 }
510
512
511 void send_dumb_hk( void )
513 void send_dumb_hk( void )
512 {
514 {
513 Packet_TM_LFR_HK_t dummy_hk_packet;
515 Packet_TM_LFR_HK_t dummy_hk_packet;
514 unsigned char *parameters;
516 unsigned char *parameters;
515 unsigned int i;
517 unsigned int i;
516 rtems_id queue_id;
518 rtems_id queue_id;
517
519
518 dummy_hk_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
520 dummy_hk_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
519 dummy_hk_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
521 dummy_hk_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
520 dummy_hk_packet.reserved = DEFAULT_RESERVED;
522 dummy_hk_packet.reserved = DEFAULT_RESERVED;
521 dummy_hk_packet.userApplication = CCSDS_USER_APP;
523 dummy_hk_packet.userApplication = CCSDS_USER_APP;
522 dummy_hk_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
524 dummy_hk_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
523 dummy_hk_packet.packetID[1] = (unsigned char) (APID_TM_HK);
525 dummy_hk_packet.packetID[1] = (unsigned char) (APID_TM_HK);
524 dummy_hk_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
526 dummy_hk_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
525 dummy_hk_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
527 dummy_hk_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
526 dummy_hk_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
528 dummy_hk_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
527 dummy_hk_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
529 dummy_hk_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
528 dummy_hk_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
530 dummy_hk_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
529 dummy_hk_packet.serviceType = TM_TYPE_HK;
531 dummy_hk_packet.serviceType = TM_TYPE_HK;
530 dummy_hk_packet.serviceSubType = TM_SUBTYPE_HK;
532 dummy_hk_packet.serviceSubType = TM_SUBTYPE_HK;
531 dummy_hk_packet.destinationID = TM_DESTINATION_ID_GROUND;
533 dummy_hk_packet.destinationID = TM_DESTINATION_ID_GROUND;
532 dummy_hk_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
534 dummy_hk_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
533 dummy_hk_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
535 dummy_hk_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
534 dummy_hk_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
536 dummy_hk_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
535 dummy_hk_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
537 dummy_hk_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
536 dummy_hk_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
538 dummy_hk_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
537 dummy_hk_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
539 dummy_hk_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
538 dummy_hk_packet.sid = SID_HK;
540 dummy_hk_packet.sid = SID_HK;
539
541
540 // init status word
542 // init status word
541 dummy_hk_packet.lfr_status_word[0] = 0xff;
543 dummy_hk_packet.lfr_status_word[0] = 0xff;
542 dummy_hk_packet.lfr_status_word[1] = 0xff;
544 dummy_hk_packet.lfr_status_word[1] = 0xff;
543 // init software version
545 // init software version
544 dummy_hk_packet.lfr_sw_version[0] = SW_VERSION_N1;
546 dummy_hk_packet.lfr_sw_version[0] = SW_VERSION_N1;
545 dummy_hk_packet.lfr_sw_version[1] = SW_VERSION_N2;
547 dummy_hk_packet.lfr_sw_version[1] = SW_VERSION_N2;
546 dummy_hk_packet.lfr_sw_version[2] = SW_VERSION_N3;
548 dummy_hk_packet.lfr_sw_version[2] = SW_VERSION_N3;
547 dummy_hk_packet.lfr_sw_version[3] = SW_VERSION_N4;
549 dummy_hk_packet.lfr_sw_version[3] = SW_VERSION_N4;
548 // init fpga version
550 // init fpga version
549 parameters = (unsigned char *) (REGS_ADDR_WAVEFORM_PICKER + 0xb0);
551 parameters = (unsigned char *) (REGS_ADDR_WAVEFORM_PICKER + 0xb0);
550 dummy_hk_packet.lfr_fpga_version[0] = parameters[1]; // n1
552 dummy_hk_packet.lfr_fpga_version[0] = parameters[1]; // n1
551 dummy_hk_packet.lfr_fpga_version[1] = parameters[2]; // n2
553 dummy_hk_packet.lfr_fpga_version[1] = parameters[2]; // n2
552 dummy_hk_packet.lfr_fpga_version[2] = parameters[3]; // n3
554 dummy_hk_packet.lfr_fpga_version[2] = parameters[3]; // n3
553
555
554 parameters = (unsigned char *) &dummy_hk_packet.hk_lfr_cpu_load;
556 parameters = (unsigned char *) &dummy_hk_packet.hk_lfr_cpu_load;
555
557
556 for (i=0; i<100; i++)
558 for (i=0; i<100; i++)
557 {
559 {
558 parameters[i] = 0xff;
560 parameters[i] = 0xff;
559 }
561 }
560
562
561 get_message_queue_id_send( &queue_id );
563 get_message_queue_id_send( &queue_id );
562
564
563 rtems_message_queue_send( queue_id, &dummy_hk_packet,
565 rtems_message_queue_send( queue_id, &dummy_hk_packet,
564 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
566 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
565 }
567 }
566
568
567 void get_temperatures( unsigned char *temperatures )
569 void get_temperatures( unsigned char *temperatures )
568 {
570 {
569 unsigned char* temp_scm_ptr;
571 unsigned char* temp_scm_ptr;
570 unsigned char* temp_pcb_ptr;
572 unsigned char* temp_pcb_ptr;
571 unsigned char* temp_fpga_ptr;
573 unsigned char* temp_fpga_ptr;
572
574
573 // SEL1 SEL0
575 // SEL1 SEL0
574 // 0 0 => PCB
576 // 0 0 => PCB
575 // 0 1 => FPGA
577 // 0 1 => FPGA
576 // 1 0 => SCM
578 // 1 0 => SCM
577
579
578 temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm;
580 temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm;
579 temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb;
581 temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb;
580 temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga;
582 temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga;
581
583
582 temperatures[0] = temp_scm_ptr[2];
584 temperatures[0] = temp_scm_ptr[2];
583 temperatures[1] = temp_scm_ptr[3];
585 temperatures[1] = temp_scm_ptr[3];
584 temperatures[2] = temp_pcb_ptr[2];
586 temperatures[2] = temp_pcb_ptr[2];
585 temperatures[3] = temp_pcb_ptr[3];
587 temperatures[3] = temp_pcb_ptr[3];
586 temperatures[4] = temp_fpga_ptr[2];
588 temperatures[4] = temp_fpga_ptr[2];
587 temperatures[5] = temp_fpga_ptr[3];
589 temperatures[5] = temp_fpga_ptr[3];
588 }
590 }
589
591
590 void get_v_e1_e2_f3( unsigned char *spacecraft_potential )
592 void get_v_e1_e2_f3( unsigned char *spacecraft_potential )
591 {
593 {
592 unsigned char* v_ptr;
594 unsigned char* v_ptr;
593 unsigned char* e1_ptr;
595 unsigned char* e1_ptr;
594 unsigned char* e2_ptr;
596 unsigned char* e2_ptr;
595
597
596 v_ptr = (unsigned char *) &waveform_picker_regs->v;
598 v_ptr = (unsigned char *) &waveform_picker_regs->v;
597 e1_ptr = (unsigned char *) &waveform_picker_regs->e1;
599 e1_ptr = (unsigned char *) &waveform_picker_regs->e1;
598 e2_ptr = (unsigned char *) &waveform_picker_regs->e2;
600 e2_ptr = (unsigned char *) &waveform_picker_regs->e2;
599
601
600 spacecraft_potential[0] = v_ptr[2];
602 spacecraft_potential[0] = v_ptr[2];
601 spacecraft_potential[1] = v_ptr[3];
603 spacecraft_potential[1] = v_ptr[3];
602 spacecraft_potential[2] = e1_ptr[2];
604 spacecraft_potential[2] = e1_ptr[2];
603 spacecraft_potential[3] = e1_ptr[3];
605 spacecraft_potential[3] = e1_ptr[3];
604 spacecraft_potential[4] = e2_ptr[2];
606 spacecraft_potential[4] = e2_ptr[2];
605 spacecraft_potential[5] = e2_ptr[3];
607 spacecraft_potential[5] = e2_ptr[3];
606 }
608 }
607
609
608 void get_cpu_load( unsigned char *resource_statistics )
610 void get_cpu_load( unsigned char *resource_statistics )
609 {
611 {
610 unsigned char cpu_load;
612 unsigned char cpu_load;
611
613
612 cpu_load = lfr_rtems_cpu_usage_report();
614 cpu_load = lfr_rtems_cpu_usage_report();
613
615
614 // HK_LFR_CPU_LOAD
616 // HK_LFR_CPU_LOAD
615 resource_statistics[0] = cpu_load;
617 resource_statistics[0] = cpu_load;
616
618
617 // HK_LFR_CPU_LOAD_MAX
619 // HK_LFR_CPU_LOAD_MAX
618 if (cpu_load > resource_statistics[1])
620 if (cpu_load > resource_statistics[1])
619 {
621 {
620 resource_statistics[1] = cpu_load;
622 resource_statistics[1] = cpu_load;
621 }
623 }
622
624
623 // CPU_LOAD_AVE
625 // CPU_LOAD_AVE
624 resource_statistics[2] = 0;
626 resource_statistics[2] = 0;
625
627
626 #ifndef PRINT_TASK_STATISTICS
628 #ifndef PRINT_TASK_STATISTICS
627 rtems_cpu_usage_reset();
629 rtems_cpu_usage_reset();
628 #endif
630 #endif
629
631
630 }
632 }
631
633
632 void set_hk_lfr_sc_potential_flag( bool state )
634 void set_hk_lfr_sc_potential_flag( bool state )
633 {
635 {
634 if (state == true)
636 if (state == true)
635 {
637 {
636 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x40; // [0100 0000]
638 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x40; // [0100 0000]
637 }
639 }
638 else
640 else
639 {
641 {
640 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xbf; // [1011 1111]
642 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xbf; // [1011 1111]
641 }
643 }
642 }
644 }
643
645
644 void set_hk_lfr_mag_fields_flag( bool state )
646 void set_hk_lfr_mag_fields_flag( bool state )
645 {
647 {
646 if (state == true)
648 if (state == true)
647 {
649 {
648 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x20; // [0010 0000]
650 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x20; // [0010 0000]
649 }
651 }
650 else
652 else
651 {
653 {
652 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xd7; // [1101 1111]
654 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xd7; // [1101 1111]
653 }
655 }
654 }
656 }
655
657
656 void set_sy_lfr_watchdog_enabled( bool state )
658 void set_sy_lfr_watchdog_enabled( bool state )
657 {
659 {
658 if (state == true)
660 if (state == true)
659 {
661 {
660 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x10; // [0001 0000]
662 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x10; // [0001 0000]
661 }
663 }
662 else
664 else
663 {
665 {
664 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xef; // [1110 1111]
666 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xef; // [1110 1111]
665 }
667 }
666 }
668 }
667
669
668 void set_hk_lfr_calib_enable( bool state )
670 void set_hk_lfr_calib_enable( bool state )
669 {
671 {
670 if (state == true)
672 if (state == true)
671 {
673 {
672 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x08; // [0000 1000]
674 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x08; // [0000 1000]
673 }
675 }
674 else
676 else
675 {
677 {
676 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xf7; // [1111 0111]
678 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xf7; // [1111 0111]
677 }
679 }
678 }
680 }
679
681
680 void set_hk_lfr_reset_cause( enum lfr_reset_cause_t lfr_reset_cause )
682 void set_hk_lfr_reset_cause( enum lfr_reset_cause_t lfr_reset_cause )
681 {
683 {
684 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xf8; // [1111 1000]
685
682 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1]
686 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1]
683 | (lfr_reset_cause & 0x07 ); // [0000 0111]
687 | (lfr_reset_cause & 0x07 ); // [0000 0111]
688
684 }
689 }
685
690
686 void hk_lfr_le_me_he_update()
691 void hk_lfr_le_me_he_update()
687 {
692 {
688 unsigned int hk_lfr_le_cnt;
693 unsigned int hk_lfr_le_cnt;
689 unsigned int hk_lfr_me_cnt;
694 unsigned int hk_lfr_me_cnt;
690 unsigned int hk_lfr_he_cnt;
695 unsigned int hk_lfr_he_cnt;
691
696
692 hk_lfr_le_cnt = 0;
697 hk_lfr_le_cnt = 0;
693 hk_lfr_me_cnt = 0;
698 hk_lfr_me_cnt = 0;
694 hk_lfr_he_cnt = 0;
699 hk_lfr_he_cnt = 0;
695
700
696 //update the low severity error counter
701 //update the low severity error counter
697 hk_lfr_le_cnt =
702 hk_lfr_le_cnt =
698 housekeeping_packet.hk_lfr_dpu_spw_parity
703 housekeeping_packet.hk_lfr_dpu_spw_parity
699 + housekeeping_packet.hk_lfr_dpu_spw_disconnect
704 + housekeeping_packet.hk_lfr_dpu_spw_disconnect
700 + housekeeping_packet.hk_lfr_dpu_spw_escape
705 + housekeeping_packet.hk_lfr_dpu_spw_escape
701 + housekeeping_packet.hk_lfr_dpu_spw_credit
706 + housekeeping_packet.hk_lfr_dpu_spw_credit
702 + housekeeping_packet.hk_lfr_dpu_spw_write_sync
707 + housekeeping_packet.hk_lfr_dpu_spw_write_sync
703 + housekeeping_packet.hk_lfr_timecode_erroneous
708 + housekeeping_packet.hk_lfr_timecode_erroneous
704 + housekeeping_packet.hk_lfr_timecode_missing
709 + housekeeping_packet.hk_lfr_timecode_missing
705 + housekeeping_packet.hk_lfr_timecode_invalid
710 + housekeeping_packet.hk_lfr_timecode_invalid
706 + housekeeping_packet.hk_lfr_time_timecode_it
711 + housekeeping_packet.hk_lfr_time_timecode_it
707 + housekeeping_packet.hk_lfr_time_not_synchro
712 + housekeeping_packet.hk_lfr_time_not_synchro
708 + housekeeping_packet.hk_lfr_time_timecode_ctr;
713 + housekeeping_packet.hk_lfr_time_timecode_ctr;
709 // housekeeping_packet.hk_lfr_dpu_spw_rx_ahb => not handled by the grspw driver
714 // housekeeping_packet.hk_lfr_dpu_spw_rx_ahb => not handled by the grspw driver
710 // housekeeping_packet.hk_lfr_dpu_spw_tx_ahb => not handled by the grspw driver
715 // housekeeping_packet.hk_lfr_dpu_spw_tx_ahb => not handled by the grspw driver
711
716
712 //update the medium severity error counter
717 //update the medium severity error counter
713 hk_lfr_me_cnt =
718 hk_lfr_me_cnt =
714 housekeeping_packet.hk_lfr_dpu_spw_early_eop
719 housekeeping_packet.hk_lfr_dpu_spw_early_eop
715 + housekeeping_packet.hk_lfr_dpu_spw_invalid_addr
720 + housekeeping_packet.hk_lfr_dpu_spw_invalid_addr
716 + housekeeping_packet.hk_lfr_dpu_spw_eep
721 + housekeeping_packet.hk_lfr_dpu_spw_eep
717 + housekeeping_packet.hk_lfr_dpu_spw_rx_too_big;
722 + housekeeping_packet.hk_lfr_dpu_spw_rx_too_big;
718
723
719 //update the high severity error counter
724 //update the high severity error counter
720 hk_lfr_he_cnt = 0;
725 hk_lfr_he_cnt = 0;
721
726
722 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
727 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
723 // LE
728 // LE
724 housekeeping_packet.hk_lfr_le_cnt[0] = (unsigned char) ((hk_lfr_le_cnt & 0xff00) >> 8);
729 housekeeping_packet.hk_lfr_le_cnt[0] = (unsigned char) ((hk_lfr_le_cnt & 0xff00) >> 8);
725 housekeeping_packet.hk_lfr_le_cnt[1] = (unsigned char) (hk_lfr_le_cnt & 0x00ff);
730 housekeeping_packet.hk_lfr_le_cnt[1] = (unsigned char) (hk_lfr_le_cnt & 0x00ff);
726 // ME
731 // ME
727 housekeeping_packet.hk_lfr_me_cnt[0] = (unsigned char) ((hk_lfr_me_cnt & 0xff00) >> 8);
732 housekeeping_packet.hk_lfr_me_cnt[0] = (unsigned char) ((hk_lfr_me_cnt & 0xff00) >> 8);
728 housekeeping_packet.hk_lfr_me_cnt[1] = (unsigned char) (hk_lfr_me_cnt & 0x00ff);
733 housekeeping_packet.hk_lfr_me_cnt[1] = (unsigned char) (hk_lfr_me_cnt & 0x00ff);
729 // HE
734 // HE
730 housekeeping_packet.hk_lfr_he_cnt[0] = (unsigned char) ((hk_lfr_he_cnt & 0xff00) >> 8);
735 housekeeping_packet.hk_lfr_he_cnt[0] = (unsigned char) ((hk_lfr_he_cnt & 0xff00) >> 8);
731 housekeeping_packet.hk_lfr_he_cnt[1] = (unsigned char) (hk_lfr_he_cnt & 0x00ff);
736 housekeeping_packet.hk_lfr_he_cnt[1] = (unsigned char) (hk_lfr_he_cnt & 0x00ff);
732
737
733 }
738 }
734
739
735 void set_hk_lfr_time_not_synchro()
740 void set_hk_lfr_time_not_synchro()
736 {
741 {
737 static unsigned char synchroLost = 1;
742 static unsigned char synchroLost = 1;
738 int synchronizationBit;
743 int synchronizationBit;
739
744
740 // get the synchronization bit
745 // get the synchronization bit
741 synchronizationBit = (time_management_regs->coarse_time & 0x80000000) >> 31; // 1000 0000 0000 0000
746 synchronizationBit = (time_management_regs->coarse_time & 0x80000000) >> 31; // 1000 0000 0000 0000
742
747
743 switch (synchronizationBit)
748 switch (synchronizationBit)
744 {
749 {
745 case 0:
750 case 0:
746 if (synchroLost == 1)
751 if (synchroLost == 1)
747 {
752 {
748 synchroLost = 0;
753 synchroLost = 0;
749 }
754 }
750 break;
755 break;
751 case 1:
756 case 1:
752 if (synchroLost == 0 )
757 if (synchroLost == 0 )
753 {
758 {
754 synchroLost = 1;
759 synchroLost = 1;
755 increase_unsigned_char_counter(&housekeeping_packet.hk_lfr_time_not_synchro);
760 increase_unsigned_char_counter(&housekeeping_packet.hk_lfr_time_not_synchro);
756 update_hk_lfr_last_er_fields( RID_LE_LFR_TIME, CODE_NOT_SYNCHRO );
761 update_hk_lfr_last_er_fields( RID_LE_LFR_TIME, CODE_NOT_SYNCHRO );
757 }
762 }
758 break;
763 break;
759 default:
764 default:
760 PRINTF1("in hk_lfr_time_not_synchro *** unexpected value for synchronizationBit = %d\n", synchronizationBit);
765 PRINTF1("in hk_lfr_time_not_synchro *** unexpected value for synchronizationBit = %d\n", synchronizationBit);
761 break;
766 break;
762 }
767 }
763
768
764 }
769 }
765
770
766 void set_hk_lfr_ahb_correctable()
771 void set_hk_lfr_ahb_correctable()
767 {
772 {
768 /** This function builds the error counter hk_lfr_ahb_correctable using the statistics provided
773 /** This function builds the error counter hk_lfr_ahb_correctable using the statistics provided
769 * by the Cache Control Register (ASI 2, offset 0) and in the Register Protection Control Register (ASR16) on the
774 * by the Cache Control Register (ASI 2, offset 0) and in the Register Protection Control Register (ASR16) on the
770 * detected errors in the cache, in the integer unit and in the floating point unit.
775 * detected errors in the cache, in the integer unit and in the floating point unit.
771 *
776 *
772 * @param void
777 * @param void
773 *
778 *
774 * @return void
779 * @return void
775 *
780 *
776 * All errors are summed to set the value of the hk_lfr_ahb_correctable counter.
781 * All errors are summed to set the value of the hk_lfr_ahb_correctable counter.
777 *
782 *
778 */
783 */
779
784
780 unsigned int ahb_correctable;
785 unsigned int ahb_correctable;
781 unsigned int instructionErrorCounter;
786 unsigned int instructionErrorCounter;
782 unsigned int dataErrorCounter;
787 unsigned int dataErrorCounter;
783 unsigned int fprfErrorCounter;
788 unsigned int fprfErrorCounter;
784 unsigned int iurfErrorCounter;
789 unsigned int iurfErrorCounter;
785
790
786 CCR_getInstructionAndDataErrorCounters( &instructionErrorCounter, &dataErrorCounter);
791 CCR_getInstructionAndDataErrorCounters( &instructionErrorCounter, &dataErrorCounter);
787 ASR16_get_FPRF_IURF_ErrorCounters( &fprfErrorCounter, &iurfErrorCounter);
792 ASR16_get_FPRF_IURF_ErrorCounters( &fprfErrorCounter, &iurfErrorCounter);
788
793
789 ahb_correctable = instructionErrorCounter
794 ahb_correctable = instructionErrorCounter
790 + dataErrorCounter
795 + dataErrorCounter
791 + fprfErrorCounter
796 + fprfErrorCounter
792 + iurfErrorCounter
797 + iurfErrorCounter
793 + housekeeping_packet.hk_lfr_ahb_correctable;
798 + housekeeping_packet.hk_lfr_ahb_correctable;
794
799
795 housekeeping_packet.hk_lfr_ahb_correctable = (unsigned char) (ahb_correctable & 0xff); // [1111 1111]
800 housekeeping_packet.hk_lfr_ahb_correctable = (unsigned char) (ahb_correctable & 0xff); // [1111 1111]
796
801
797 }
802 }
@@ -1,1585 +1,1598
1 /** Functions related to the SpaceWire interface.
1 /** Functions related to the SpaceWire interface.
2 *
2 *
3 * @file
3 * @file
4 * @author P. LEROY
4 * @author P. LEROY
5 *
5 *
6 * A group of functions to handle SpaceWire transmissions:
6 * A group of functions to handle SpaceWire transmissions:
7 * - configuration of the SpaceWire link
7 * - configuration of the SpaceWire link
8 * - SpaceWire related interruption requests processing
8 * - SpaceWire related interruption requests processing
9 * - transmission of TeleMetry packets by a dedicated RTEMS task
9 * - transmission of TeleMetry packets by a dedicated RTEMS task
10 * - reception of TeleCommands by a dedicated RTEMS task
10 * - reception of TeleCommands by a dedicated RTEMS task
11 *
11 *
12 */
12 */
13
13
14 #include "fsw_spacewire.h"
14 #include "fsw_spacewire.h"
15
15
16 rtems_name semq_name;
16 rtems_name semq_name;
17 rtems_id semq_id;
17 rtems_id semq_id;
18
18
19 //*****************
19 //*****************
20 // waveform headers
20 // waveform headers
21 Header_TM_LFR_SCIENCE_CWF_t headerCWF;
21 Header_TM_LFR_SCIENCE_CWF_t headerCWF;
22 Header_TM_LFR_SCIENCE_SWF_t headerSWF;
22 Header_TM_LFR_SCIENCE_SWF_t headerSWF;
23 Header_TM_LFR_SCIENCE_ASM_t headerASM;
23 Header_TM_LFR_SCIENCE_ASM_t headerASM;
24
24
25 unsigned char previousTimecodeCtr = 0;
25 unsigned char previousTimecodeCtr = 0;
26 unsigned int *grspwPtr = (unsigned int *) (REGS_ADDR_GRSPW + APB_OFFSET_GRSPW_TIME_REGISTER);
26 unsigned int *grspwPtr = (unsigned int *) (REGS_ADDR_GRSPW + APB_OFFSET_GRSPW_TIME_REGISTER);
27
27
28 //***********
28 //***********
29 // RTEMS TASK
29 // RTEMS TASK
30 rtems_task spiq_task(rtems_task_argument unused)
30 rtems_task spiq_task(rtems_task_argument unused)
31 {
31 {
32 /** This RTEMS task is awaken by an rtems_event sent by the interruption subroutine of the SpaceWire driver.
32 /** This RTEMS task is awaken by an rtems_event sent by the interruption subroutine of the SpaceWire driver.
33 *
33 *
34 * @param unused is the starting argument of the RTEMS task
34 * @param unused is the starting argument of the RTEMS task
35 *
35 *
36 */
36 */
37
37
38 rtems_event_set event_out;
38 rtems_event_set event_out;
39 rtems_status_code status;
39 rtems_status_code status;
40 int linkStatus;
40 int linkStatus;
41
41
42 BOOT_PRINTF("in SPIQ *** \n")
42 BOOT_PRINTF("in SPIQ *** \n")
43
43
44 while(true){
44 while(true){
45 rtems_event_receive(SPW_LINKERR_EVENT, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an SPW_LINKERR_EVENT
45 rtems_event_receive(SPW_LINKERR_EVENT, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an SPW_LINKERR_EVENT
46 PRINTF("in SPIQ *** got SPW_LINKERR_EVENT\n")
46 PRINTF("in SPIQ *** got SPW_LINKERR_EVENT\n")
47
47
48 // [0] SUSPEND RECV AND SEND TASKS
48 // [0] SUSPEND RECV AND SEND TASKS
49 status = rtems_task_suspend( Task_id[ TASKID_RECV ] );
49 status = rtems_task_suspend( Task_id[ TASKID_RECV ] );
50 if ( status != RTEMS_SUCCESSFUL ) {
50 if ( status != RTEMS_SUCCESSFUL ) {
51 PRINTF("in SPIQ *** ERR suspending RECV Task\n")
51 PRINTF("in SPIQ *** ERR suspending RECV Task\n")
52 }
52 }
53 status = rtems_task_suspend( Task_id[ TASKID_SEND ] );
53 status = rtems_task_suspend( Task_id[ TASKID_SEND ] );
54 if ( status != RTEMS_SUCCESSFUL ) {
54 if ( status != RTEMS_SUCCESSFUL ) {
55 PRINTF("in SPIQ *** ERR suspending SEND Task\n")
55 PRINTF("in SPIQ *** ERR suspending SEND Task\n")
56 }
56 }
57
57
58 // [1] CHECK THE LINK
58 // [1] CHECK THE LINK
59 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (1)
59 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (1)
60 if ( linkStatus != 5) {
60 if ( linkStatus != 5) {
61 PRINTF1("in SPIQ *** linkStatus %d, wait...\n", linkStatus)
61 PRINTF1("in SPIQ *** linkStatus %d, wait...\n", linkStatus)
62 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
62 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
63 }
63 }
64
64
65 // [2] RECHECK THE LINK AFTER SY_LFR_DPU_CONNECT_TIMEOUT
65 // [2] RECHECK THE LINK AFTER SY_LFR_DPU_CONNECT_TIMEOUT
66 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (2)
66 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (2)
67 if ( linkStatus != 5 ) // [2.a] not in run state, reset the link
67 if ( linkStatus != 5 ) // [2.a] not in run state, reset the link
68 {
68 {
69 spacewire_read_statistics();
69 spacewire_read_statistics();
70 status = spacewire_several_connect_attemps( );
70 status = spacewire_several_connect_attemps( );
71 }
71 }
72 else // [2.b] in run state, start the link
72 else // [2.b] in run state, start the link
73 {
73 {
74 status = spacewire_stop_and_start_link( fdSPW ); // start the link
74 status = spacewire_stop_and_start_link( fdSPW ); // start the link
75 if ( status != RTEMS_SUCCESSFUL)
75 if ( status != RTEMS_SUCCESSFUL)
76 {
76 {
77 PRINTF1("in SPIQ *** ERR spacewire_stop_and_start_link %d\n", status)
77 PRINTF1("in SPIQ *** ERR spacewire_stop_and_start_link %d\n", status)
78 }
78 }
79 }
79 }
80
80
81 // [3] COMPLETE RECOVERY ACTION AFTER SY_LFR_DPU_CONNECT_ATTEMPTS
81 // [3] COMPLETE RECOVERY ACTION AFTER SY_LFR_DPU_CONNECT_ATTEMPTS
82 if ( status == RTEMS_SUCCESSFUL ) // [3.a] the link is in run state and has been started successfully
82 if ( status == RTEMS_SUCCESSFUL ) // [3.a] the link is in run state and has been started successfully
83 {
83 {
84 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
84 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
85 if ( status != RTEMS_SUCCESSFUL ) {
85 if ( status != RTEMS_SUCCESSFUL ) {
86 PRINTF("in SPIQ *** ERR resuming SEND Task\n")
86 PRINTF("in SPIQ *** ERR resuming SEND Task\n")
87 }
87 }
88 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
88 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
89 if ( status != RTEMS_SUCCESSFUL ) {
89 if ( status != RTEMS_SUCCESSFUL ) {
90 PRINTF("in SPIQ *** ERR resuming RECV Task\n")
90 PRINTF("in SPIQ *** ERR resuming RECV Task\n")
91 }
91 }
92 }
92 }
93 else // [3.b] the link is not in run state, go in STANDBY mode
93 else // [3.b] the link is not in run state, go in STANDBY mode
94 {
94 {
95 status = enter_mode_standby();
95 status = enter_mode_standby();
96 if ( status != RTEMS_SUCCESSFUL )
96 if ( status != RTEMS_SUCCESSFUL )
97 {
97 {
98 PRINTF1("in SPIQ *** ERR enter_standby_mode *** code %d\n", status)
98 PRINTF1("in SPIQ *** ERR enter_standby_mode *** code %d\n", status)
99 }
99 }
100 {
100 {
101 updateLFRCurrentMode( LFR_MODE_STANDBY );
101 updateLFRCurrentMode( LFR_MODE_STANDBY );
102 }
102 }
103 // wake the LINK task up to wait for the link recovery
103 // wake the LINK task up to wait for the link recovery
104 status = rtems_event_send ( Task_id[TASKID_LINK], RTEMS_EVENT_0 );
104 status = rtems_event_send ( Task_id[TASKID_LINK], RTEMS_EVENT_0 );
105 status = rtems_task_suspend( RTEMS_SELF );
105 status = rtems_task_suspend( RTEMS_SELF );
106 }
106 }
107 }
107 }
108 }
108 }
109
109
110 rtems_task recv_task( rtems_task_argument unused )
110 rtems_task recv_task( rtems_task_argument unused )
111 {
111 {
112 /** This RTEMS task is dedicated to the reception of incoming TeleCommands.
112 /** This RTEMS task is dedicated to the reception of incoming TeleCommands.
113 *
113 *
114 * @param unused is the starting argument of the RTEMS task
114 * @param unused is the starting argument of the RTEMS task
115 *
115 *
116 * The RECV task blocks on a call to the read system call, waiting for incoming SpaceWire data. When unblocked:
116 * The RECV task blocks on a call to the read system call, waiting for incoming SpaceWire data. When unblocked:
117 * 1. It reads the incoming data.
117 * 1. It reads the incoming data.
118 * 2. Launches the acceptance procedure.
118 * 2. Launches the acceptance procedure.
119 * 3. If the Telecommand is valid, sends it to a dedicated RTEMS message queue.
119 * 3. If the Telecommand is valid, sends it to a dedicated RTEMS message queue.
120 *
120 *
121 */
121 */
122
122
123 int len;
123 int len;
124 ccsdsTelecommandPacket_t currentTC;
124 ccsdsTelecommandPacket_t currentTC;
125 unsigned char computed_CRC[ 2 ];
125 unsigned char computed_CRC[ 2 ];
126 unsigned char currentTC_LEN_RCV[ 2 ];
126 unsigned char currentTC_LEN_RCV[ 2 ];
127 unsigned char destinationID;
127 unsigned char destinationID;
128 unsigned int estimatedPacketLength;
128 unsigned int estimatedPacketLength;
129 unsigned int parserCode;
129 unsigned int parserCode;
130 rtems_status_code status;
130 rtems_status_code status;
131 rtems_id queue_recv_id;
131 rtems_id queue_recv_id;
132 rtems_id queue_send_id;
132 rtems_id queue_send_id;
133
133
134 initLookUpTableForCRC(); // the table is used to compute Cyclic Redundancy Codes
134 initLookUpTableForCRC(); // the table is used to compute Cyclic Redundancy Codes
135
135
136 status = get_message_queue_id_recv( &queue_recv_id );
136 status = get_message_queue_id_recv( &queue_recv_id );
137 if (status != RTEMS_SUCCESSFUL)
137 if (status != RTEMS_SUCCESSFUL)
138 {
138 {
139 PRINTF1("in RECV *** ERR get_message_queue_id_recv %d\n", status)
139 PRINTF1("in RECV *** ERR get_message_queue_id_recv %d\n", status)
140 }
140 }
141
141
142 status = get_message_queue_id_send( &queue_send_id );
142 status = get_message_queue_id_send( &queue_send_id );
143 if (status != RTEMS_SUCCESSFUL)
143 if (status != RTEMS_SUCCESSFUL)
144 {
144 {
145 PRINTF1("in RECV *** ERR get_message_queue_id_send %d\n", status)
145 PRINTF1("in RECV *** ERR get_message_queue_id_send %d\n", status)
146 }
146 }
147
147
148 BOOT_PRINTF("in RECV *** \n")
148 BOOT_PRINTF("in RECV *** \n")
149
149
150 while(1)
150 while(1)
151 {
151 {
152 len = read( fdSPW, (char*) &currentTC, CCSDS_TC_PKT_MAX_SIZE ); // the call to read is blocking
152 len = read( fdSPW, (char*) &currentTC, CCSDS_TC_PKT_MAX_SIZE ); // the call to read is blocking
153 if (len == -1){ // error during the read call
153 if (len == -1){ // error during the read call
154 PRINTF1("in RECV *** last read call returned -1, ERRNO %d\n", errno)
154 PRINTF1("in RECV *** last read call returned -1, ERRNO %d\n", errno)
155 }
155 }
156 else {
156 else {
157 if ( (len+1) < CCSDS_TC_PKT_MIN_SIZE ) {
157 if ( (len+1) < CCSDS_TC_PKT_MIN_SIZE ) {
158 PRINTF("in RECV *** packet lenght too short\n")
158 PRINTF("in RECV *** packet lenght too short\n")
159 }
159 }
160 else {
160 else {
161 estimatedPacketLength = (unsigned int) (len - CCSDS_TC_TM_PACKET_OFFSET - 3); // => -3 is for Prot ID, Reserved and User App bytes
161 estimatedPacketLength = (unsigned int) (len - CCSDS_TC_TM_PACKET_OFFSET - 3); // => -3 is for Prot ID, Reserved and User App bytes
162 currentTC_LEN_RCV[ 0 ] = (unsigned char) (estimatedPacketLength >> 8);
162 currentTC_LEN_RCV[ 0 ] = (unsigned char) (estimatedPacketLength >> 8);
163 currentTC_LEN_RCV[ 1 ] = (unsigned char) (estimatedPacketLength );
163 currentTC_LEN_RCV[ 1 ] = (unsigned char) (estimatedPacketLength );
164 // CHECK THE TC
164 // CHECK THE TC
165 parserCode = tc_parser( &currentTC, estimatedPacketLength, computed_CRC ) ;
165 parserCode = tc_parser( &currentTC, estimatedPacketLength, computed_CRC ) ;
166 if ( (parserCode == ILLEGAL_APID) || (parserCode == WRONG_LEN_PKT)
166 if ( (parserCode == ILLEGAL_APID) || (parserCode == WRONG_LEN_PKT)
167 || (parserCode == INCOR_CHECKSUM) || (parserCode == ILL_TYPE)
167 || (parserCode == INCOR_CHECKSUM) || (parserCode == ILL_TYPE)
168 || (parserCode == ILL_SUBTYPE) || (parserCode == WRONG_APP_DATA)
168 || (parserCode == ILL_SUBTYPE) || (parserCode == WRONG_APP_DATA)
169 || (parserCode == WRONG_SRC_ID) )
169 || (parserCode == WRONG_SRC_ID) )
170 { // send TM_LFR_TC_EXE_CORRUPTED
170 { // send TM_LFR_TC_EXE_CORRUPTED
171 PRINTF1("TC corrupted received, with code: %d\n", parserCode)
171 PRINTF1("TC corrupted received, with code: %d\n", parserCode)
172 if ( !( (currentTC.serviceType==TC_TYPE_TIME) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_TIME) )
172 if ( !( (currentTC.serviceType==TC_TYPE_TIME) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_TIME) )
173 &&
173 &&
174 !( (currentTC.serviceType==TC_TYPE_GEN) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_INFO))
174 !( (currentTC.serviceType==TC_TYPE_GEN) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_INFO))
175 )
175 )
176 {
176 {
177 if ( parserCode == WRONG_SRC_ID )
177 if ( parserCode == WRONG_SRC_ID )
178 {
178 {
179 destinationID = SID_TC_GROUND;
179 destinationID = SID_TC_GROUND;
180 }
180 }
181 else
181 else
182 {
182 {
183 destinationID = currentTC.sourceID;
183 destinationID = currentTC.sourceID;
184 }
184 }
185 send_tm_lfr_tc_exe_corrupted( &currentTC, queue_send_id,
185 send_tm_lfr_tc_exe_corrupted( &currentTC, queue_send_id,
186 computed_CRC, currentTC_LEN_RCV,
186 computed_CRC, currentTC_LEN_RCV,
187 destinationID );
187 destinationID );
188 }
188 }
189 }
189 }
190 else
190 else
191 { // send valid TC to the action launcher
191 { // send valid TC to the action launcher
192 status = rtems_message_queue_send( queue_recv_id, &currentTC,
192 status = rtems_message_queue_send( queue_recv_id, &currentTC,
193 estimatedPacketLength + CCSDS_TC_TM_PACKET_OFFSET + 3);
193 estimatedPacketLength + CCSDS_TC_TM_PACKET_OFFSET + 3);
194 }
194 }
195 }
195 }
196 }
196 }
197
197
198 update_queue_max_count( queue_recv_id, &hk_lfr_q_rv_fifo_size_max );
198 update_queue_max_count( queue_recv_id, &hk_lfr_q_rv_fifo_size_max );
199
199
200 }
200 }
201 }
201 }
202
202
203 rtems_task send_task( rtems_task_argument argument)
203 rtems_task send_task( rtems_task_argument argument)
204 {
204 {
205 /** This RTEMS task is dedicated to the transmission of TeleMetry packets.
205 /** This RTEMS task is dedicated to the transmission of TeleMetry packets.
206 *
206 *
207 * @param unused is the starting argument of the RTEMS task
207 * @param unused is the starting argument of the RTEMS task
208 *
208 *
209 * The SEND task waits for a message to become available in the dedicated RTEMS queue. When a message arrives:
209 * The SEND task waits for a message to become available in the dedicated RTEMS queue. When a message arrives:
210 * - if the first byte is equal to CCSDS_DESTINATION_ID, the message is sent as is using the write system call.
210 * - if the first byte is equal to CCSDS_DESTINATION_ID, the message is sent as is using the write system call.
211 * - if the first byte is not equal to CCSDS_DESTINATION_ID, the message is handled as a spw_ioctl_pkt_send. After
211 * - if the first byte is not equal to CCSDS_DESTINATION_ID, the message is handled as a spw_ioctl_pkt_send. After
212 * analyzis, the packet is sent either using the write system call or using the ioctl call SPACEWIRE_IOCTRL_SEND, depending on the
212 * analyzis, the packet is sent either using the write system call or using the ioctl call SPACEWIRE_IOCTRL_SEND, depending on the
213 * data it contains.
213 * data it contains.
214 *
214 *
215 */
215 */
216
216
217 rtems_status_code status; // RTEMS status code
217 rtems_status_code status; // RTEMS status code
218 char incomingData[MSG_QUEUE_SIZE_SEND]; // incoming data buffer
218 char incomingData[MSG_QUEUE_SIZE_SEND]; // incoming data buffer
219 ring_node *incomingRingNodePtr;
219 ring_node *incomingRingNodePtr;
220 int ring_node_address;
220 int ring_node_address;
221 char *charPtr;
221 char *charPtr;
222 spw_ioctl_pkt_send *spw_ioctl_send;
222 spw_ioctl_pkt_send *spw_ioctl_send;
223 size_t size; // size of the incoming TC packet
223 size_t size; // size of the incoming TC packet
224 rtems_id queue_send_id;
224 rtems_id queue_send_id;
225 unsigned int sid;
225 unsigned int sid;
226 unsigned char sidAsUnsignedChar;
226 unsigned char sidAsUnsignedChar;
227 unsigned char type;
227 unsigned char type;
228
228
229 incomingRingNodePtr = NULL;
229 incomingRingNodePtr = NULL;
230 ring_node_address = 0;
230 ring_node_address = 0;
231 charPtr = (char *) &ring_node_address;
231 charPtr = (char *) &ring_node_address;
232 sid = 0;
232 sid = 0;
233 sidAsUnsignedChar = 0;
233 sidAsUnsignedChar = 0;
234
234
235 init_header_cwf( &headerCWF );
235 init_header_cwf( &headerCWF );
236 init_header_swf( &headerSWF );
236 init_header_swf( &headerSWF );
237 init_header_asm( &headerASM );
237 init_header_asm( &headerASM );
238
238
239 status = get_message_queue_id_send( &queue_send_id );
239 status = get_message_queue_id_send( &queue_send_id );
240 if (status != RTEMS_SUCCESSFUL)
240 if (status != RTEMS_SUCCESSFUL)
241 {
241 {
242 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
242 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
243 }
243 }
244
244
245 BOOT_PRINTF("in SEND *** \n")
245 BOOT_PRINTF("in SEND *** \n")
246
246
247 while(1)
247 while(1)
248 {
248 {
249 status = rtems_message_queue_receive( queue_send_id, incomingData, &size,
249 status = rtems_message_queue_receive( queue_send_id, incomingData, &size,
250 RTEMS_WAIT, RTEMS_NO_TIMEOUT );
250 RTEMS_WAIT, RTEMS_NO_TIMEOUT );
251
251
252 if (status!=RTEMS_SUCCESSFUL)
252 if (status!=RTEMS_SUCCESSFUL)
253 {
253 {
254 PRINTF1("in SEND *** (1) ERR = %d\n", status)
254 PRINTF1("in SEND *** (1) ERR = %d\n", status)
255 }
255 }
256 else
256 else
257 {
257 {
258 if ( size == sizeof(ring_node*) )
258 if ( size == sizeof(ring_node*) )
259 {
259 {
260 charPtr[0] = incomingData[0];
260 charPtr[0] = incomingData[0];
261 charPtr[1] = incomingData[1];
261 charPtr[1] = incomingData[1];
262 charPtr[2] = incomingData[2];
262 charPtr[2] = incomingData[2];
263 charPtr[3] = incomingData[3];
263 charPtr[3] = incomingData[3];
264 incomingRingNodePtr = (ring_node*) ring_node_address;
264 incomingRingNodePtr = (ring_node*) ring_node_address;
265 sid = incomingRingNodePtr->sid;
265 sid = incomingRingNodePtr->sid;
266 if ( (sid==SID_NORM_CWF_LONG_F3)
266 if ( (sid==SID_NORM_CWF_LONG_F3)
267 || (sid==SID_BURST_CWF_F2 )
267 || (sid==SID_BURST_CWF_F2 )
268 || (sid==SID_SBM1_CWF_F1 )
268 || (sid==SID_SBM1_CWF_F1 )
269 || (sid==SID_SBM2_CWF_F2 ))
269 || (sid==SID_SBM2_CWF_F2 ))
270 {
270 {
271 spw_send_waveform_CWF( incomingRingNodePtr, &headerCWF );
271 spw_send_waveform_CWF( incomingRingNodePtr, &headerCWF );
272 }
272 }
273 else if ( (sid==SID_NORM_SWF_F0) || (sid== SID_NORM_SWF_F1) || (sid==SID_NORM_SWF_F2) )
273 else if ( (sid==SID_NORM_SWF_F0) || (sid== SID_NORM_SWF_F1) || (sid==SID_NORM_SWF_F2) )
274 {
274 {
275 spw_send_waveform_SWF( incomingRingNodePtr, &headerSWF );
275 spw_send_waveform_SWF( incomingRingNodePtr, &headerSWF );
276 }
276 }
277 else if ( (sid==SID_NORM_CWF_F3) )
277 else if ( (sid==SID_NORM_CWF_F3) )
278 {
278 {
279 spw_send_waveform_CWF3_light( incomingRingNodePtr, &headerCWF );
279 spw_send_waveform_CWF3_light( incomingRingNodePtr, &headerCWF );
280 }
280 }
281 else if (sid==SID_NORM_ASM_F0)
281 else if (sid==SID_NORM_ASM_F0)
282 {
282 {
283 spw_send_asm_f0( incomingRingNodePtr, &headerASM );
283 spw_send_asm_f0( incomingRingNodePtr, &headerASM );
284 }
284 }
285 else if (sid==SID_NORM_ASM_F1)
285 else if (sid==SID_NORM_ASM_F1)
286 {
286 {
287 spw_send_asm_f1( incomingRingNodePtr, &headerASM );
287 spw_send_asm_f1( incomingRingNodePtr, &headerASM );
288 }
288 }
289 else if (sid==SID_NORM_ASM_F2)
289 else if (sid==SID_NORM_ASM_F2)
290 {
290 {
291 spw_send_asm_f2( incomingRingNodePtr, &headerASM );
291 spw_send_asm_f2( incomingRingNodePtr, &headerASM );
292 }
292 }
293 else if ( sid==TM_CODE_K_DUMP )
293 else if ( sid==TM_CODE_K_DUMP )
294 {
294 {
295 spw_send_k_dump( incomingRingNodePtr );
295 spw_send_k_dump( incomingRingNodePtr );
296 }
296 }
297 else
297 else
298 {
298 {
299 PRINTF1("unexpected sid = %d\n", sid);
299 PRINTF1("unexpected sid = %d\n", sid);
300 }
300 }
301 }
301 }
302 else if ( incomingData[0] == CCSDS_DESTINATION_ID ) // the incoming message is a ccsds packet
302 else if ( incomingData[0] == CCSDS_DESTINATION_ID ) // the incoming message is a ccsds packet
303 {
303 {
304 sidAsUnsignedChar = (unsigned char) incomingData[ PACKET_POS_PA_LFR_SID_PKT ];
304 sidAsUnsignedChar = (unsigned char) incomingData[ PACKET_POS_PA_LFR_SID_PKT ];
305 sid = sidAsUnsignedChar;
305 sid = sidAsUnsignedChar;
306 type = (unsigned char) incomingData[ PACKET_POS_SERVICE_TYPE ];
306 type = (unsigned char) incomingData[ PACKET_POS_SERVICE_TYPE ];
307 if (type == TM_TYPE_LFR_SCIENCE) // this is a BP packet, all other types are handled differently
307 if (type == TM_TYPE_LFR_SCIENCE) // this is a BP packet, all other types are handled differently
308 // SET THE SEQUENCE_CNT PARAMETER IN CASE OF BP0 OR BP1 PACKETS
308 // SET THE SEQUENCE_CNT PARAMETER IN CASE OF BP0 OR BP1 PACKETS
309 {
309 {
310 increment_seq_counter_source_id( (unsigned char*) &incomingData[ PACKET_POS_SEQUENCE_CNT ], sid );
310 increment_seq_counter_source_id( (unsigned char*) &incomingData[ PACKET_POS_SEQUENCE_CNT ], sid );
311 }
311 }
312
312
313 status = write( fdSPW, incomingData, size );
313 status = write( fdSPW, incomingData, size );
314 if (status == -1){
314 if (status == -1){
315 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
315 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
316 }
316 }
317 }
317 }
318 else // the incoming message is a spw_ioctl_pkt_send structure
318 else // the incoming message is a spw_ioctl_pkt_send structure
319 {
319 {
320 spw_ioctl_send = (spw_ioctl_pkt_send*) incomingData;
320 spw_ioctl_send = (spw_ioctl_pkt_send*) incomingData;
321 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, spw_ioctl_send );
321 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, spw_ioctl_send );
322 if (status == -1){
322 if (status == -1){
323 PRINTF2("in SEND *** (2.b) ERRNO = %d, RTEMS = %d\n", errno, status)
323 PRINTF2("in SEND *** (2.b) ERRNO = %d, RTEMS = %d\n", errno, status)
324 }
324 }
325 }
325 }
326 }
326 }
327
327
328 update_queue_max_count( queue_send_id, &hk_lfr_q_sd_fifo_size_max );
328 update_queue_max_count( queue_send_id, &hk_lfr_q_sd_fifo_size_max );
329
329
330 }
330 }
331 }
331 }
332
332
333 rtems_task link_task( rtems_task_argument argument )
333 rtems_task link_task( rtems_task_argument argument )
334 {
334 {
335 rtems_event_set event_out;
335 rtems_event_set event_out;
336 rtems_status_code status;
336 rtems_status_code status;
337 int linkStatus;
337 int linkStatus;
338
338
339 BOOT_PRINTF("in LINK ***\n")
339 BOOT_PRINTF("in LINK ***\n")
340
340
341 while(1)
341 while(1)
342 {
342 {
343 // wait for an RTEMS_EVENT
343 // wait for an RTEMS_EVENT
344 rtems_event_receive( RTEMS_EVENT_0,
344 rtems_event_receive( RTEMS_EVENT_0,
345 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
345 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
346 PRINTF("in LINK *** wait for the link\n")
346 PRINTF("in LINK *** wait for the link\n")
347 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
347 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
348 while( linkStatus != 5) // wait for the link
348 while( linkStatus != 5) // wait for the link
349 {
349 {
350 status = rtems_task_wake_after( 10 ); // monitor the link each 100ms
350 status = rtems_task_wake_after( 10 ); // monitor the link each 100ms
351 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
351 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
352 watchdog_reload();
352 watchdog_reload();
353 }
353 }
354
354
355 spacewire_read_statistics();
355 spacewire_read_statistics();
356 status = spacewire_stop_and_start_link( fdSPW );
356 status = spacewire_stop_and_start_link( fdSPW );
357
357
358 if (status != RTEMS_SUCCESSFUL)
358 if (status != RTEMS_SUCCESSFUL)
359 {
359 {
360 PRINTF1("in LINK *** ERR link not started %d\n", status)
360 PRINTF1("in LINK *** ERR link not started %d\n", status)
361 }
361 }
362 else
362 else
363 {
363 {
364 PRINTF("in LINK *** OK link started\n")
364 PRINTF("in LINK *** OK link started\n")
365 }
365 }
366
366
367 // restart the SPIQ task
367 // restart the SPIQ task
368 status = rtems_task_restart( Task_id[TASKID_SPIQ], 1 );
368 status = rtems_task_restart( Task_id[TASKID_SPIQ], 1 );
369 if ( status != RTEMS_SUCCESSFUL ) {
369 if ( status != RTEMS_SUCCESSFUL ) {
370 PRINTF("in SPIQ *** ERR restarting SPIQ Task\n")
370 PRINTF("in SPIQ *** ERR restarting SPIQ Task\n")
371 }
371 }
372
372
373 // restart RECV and SEND
373 // restart RECV and SEND
374 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
374 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
375 if ( status != RTEMS_SUCCESSFUL ) {
375 if ( status != RTEMS_SUCCESSFUL ) {
376 PRINTF("in SPIQ *** ERR restarting SEND Task\n")
376 PRINTF("in SPIQ *** ERR restarting SEND Task\n")
377 }
377 }
378 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
378 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
379 if ( status != RTEMS_SUCCESSFUL ) {
379 if ( status != RTEMS_SUCCESSFUL ) {
380 PRINTF("in SPIQ *** ERR restarting RECV Task\n")
380 PRINTF("in SPIQ *** ERR restarting RECV Task\n")
381 }
381 }
382 }
382 }
383 }
383 }
384
384
385 //****************
385 //****************
386 // OTHER FUNCTIONS
386 // OTHER FUNCTIONS
387 int spacewire_open_link( void ) // by default, the driver resets the core: [SPW_CTRL_WRITE(pDev, SPW_CTRL_RESET);]
387 int spacewire_open_link( void ) // by default, the driver resets the core: [SPW_CTRL_WRITE(pDev, SPW_CTRL_RESET);]
388 {
388 {
389 /** This function opens the SpaceWire link.
389 /** This function opens the SpaceWire link.
390 *
390 *
391 * @return a valid file descriptor in case of success, -1 in case of a failure
391 * @return a valid file descriptor in case of success, -1 in case of a failure
392 *
392 *
393 */
393 */
394 rtems_status_code status;
394 rtems_status_code status;
395
395
396 fdSPW = open(GRSPW_DEVICE_NAME, O_RDWR); // open the device. the open call resets the hardware
396 fdSPW = open(GRSPW_DEVICE_NAME, O_RDWR); // open the device. the open call resets the hardware
397 if ( fdSPW < 0 ) {
397 if ( fdSPW < 0 ) {
398 PRINTF1("ERR *** in configure_spw_link *** error opening "GRSPW_DEVICE_NAME" with ERR %d\n", errno)
398 PRINTF1("ERR *** in configure_spw_link *** error opening "GRSPW_DEVICE_NAME" with ERR %d\n", errno)
399 }
399 }
400 else
400 else
401 {
401 {
402 status = RTEMS_SUCCESSFUL;
402 status = RTEMS_SUCCESSFUL;
403 }
403 }
404
404
405 return status;
405 return status;
406 }
406 }
407
407
408 int spacewire_start_link( int fd )
408 int spacewire_start_link( int fd )
409 {
409 {
410 rtems_status_code status;
410 rtems_status_code status;
411
411
412 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
412 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
413 // -1 default hardcoded driver timeout
413 // -1 default hardcoded driver timeout
414
414
415 return status;
415 return status;
416 }
416 }
417
417
418 int spacewire_stop_and_start_link( int fd )
418 int spacewire_stop_and_start_link( int fd )
419 {
419 {
420 rtems_status_code status;
420 rtems_status_code status;
421
421
422 status = ioctl( fd, SPACEWIRE_IOCTRL_STOP); // start fails if link pDev->running != 0
422 status = ioctl( fd, SPACEWIRE_IOCTRL_STOP); // start fails if link pDev->running != 0
423 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
423 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
424 // -1 default hardcoded driver timeout
424 // -1 default hardcoded driver timeout
425
425
426 return status;
426 return status;
427 }
427 }
428
428
429 int spacewire_configure_link( int fd )
429 int spacewire_configure_link( int fd )
430 {
430 {
431 /** This function configures the SpaceWire link.
431 /** This function configures the SpaceWire link.
432 *
432 *
433 * @return GR-RTEMS-DRIVER directive status codes:
433 * @return GR-RTEMS-DRIVER directive status codes:
434 * - 22 EINVAL - Null pointer or an out of range value was given as the argument.
434 * - 22 EINVAL - Null pointer or an out of range value was given as the argument.
435 * - 16 EBUSY - Only used for SEND. Returned when no descriptors are avialble in non-blocking mode.
435 * - 16 EBUSY - Only used for SEND. Returned when no descriptors are avialble in non-blocking mode.
436 * - 88 ENOSYS - Returned for SET_DESTKEY if RMAP command handler is not available or if a non-implemented call is used.
436 * - 88 ENOSYS - Returned for SET_DESTKEY if RMAP command handler is not available or if a non-implemented call is used.
437 * - 116 ETIMEDOUT - REturned for SET_PACKET_SIZE and START if the link could not be brought up.
437 * - 116 ETIMEDOUT - REturned for SET_PACKET_SIZE and START if the link could not be brought up.
438 * - 12 ENOMEM - Returned for SET_PACKETSIZE if it was unable to allocate the new buffers.
438 * - 12 ENOMEM - Returned for SET_PACKETSIZE if it was unable to allocate the new buffers.
439 * - 5 EIO - Error when writing to grswp hardware registers.
439 * - 5 EIO - Error when writing to grswp hardware registers.
440 * - 2 ENOENT - No such file or directory
440 * - 2 ENOENT - No such file or directory
441 */
441 */
442
442
443 rtems_status_code status;
443 rtems_status_code status;
444
444
445 spacewire_set_NP(1, REGS_ADDR_GRSPW); // [N]o [P]ort force
445 spacewire_set_NP(1, REGS_ADDR_GRSPW); // [N]o [P]ort force
446 spacewire_set_RE(1, REGS_ADDR_GRSPW); // [R]MAP [E]nable, the dedicated call seems to break the no port force configuration
446 spacewire_set_RE(1, REGS_ADDR_GRSPW); // [R]MAP [E]nable, the dedicated call seems to break the no port force configuration
447
447
448 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_RXBLOCK, 1); // sets the blocking mode for reception
448 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_RXBLOCK, 1); // sets the blocking mode for reception
449 if (status!=RTEMS_SUCCESSFUL) {
449 if (status!=RTEMS_SUCCESSFUL) {
450 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_RXBLOCK\n")
450 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_RXBLOCK\n")
451 }
451 }
452 //
452 //
453 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_EVENT_ID, Task_id[TASKID_SPIQ]); // sets the task ID to which an event is sent when a
453 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_EVENT_ID, Task_id[TASKID_SPIQ]); // sets the task ID to which an event is sent when a
454 if (status!=RTEMS_SUCCESSFUL) {
454 if (status!=RTEMS_SUCCESSFUL) {
455 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_EVENT_ID\n") // link-error interrupt occurs
455 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_EVENT_ID\n") // link-error interrupt occurs
456 }
456 }
457 //
457 //
458 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_DISABLE_ERR, 0); // automatic link-disabling due to link-error interrupts
458 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_DISABLE_ERR, 0); // automatic link-disabling due to link-error interrupts
459 if (status!=RTEMS_SUCCESSFUL) {
459 if (status!=RTEMS_SUCCESSFUL) {
460 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_DISABLE_ERR\n")
460 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_DISABLE_ERR\n")
461 }
461 }
462 //
462 //
463 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ, 1); // sets the link-error interrupt bit
463 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ, 1); // sets the link-error interrupt bit
464 if (status!=RTEMS_SUCCESSFUL) {
464 if (status!=RTEMS_SUCCESSFUL) {
465 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ\n")
465 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ\n")
466 }
466 }
467 //
467 //
468 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK, 1); // transmission blocks
468 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK, 1); // transmission blocks
469 if (status!=RTEMS_SUCCESSFUL) {
469 if (status!=RTEMS_SUCCESSFUL) {
470 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK\n")
470 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK\n")
471 }
471 }
472 //
472 //
473 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL, 1); // transmission blocks when no transmission descriptor is available
473 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL, 1); // transmission blocks when no transmission descriptor is available
474 if (status!=RTEMS_SUCCESSFUL) {
474 if (status!=RTEMS_SUCCESSFUL) {
475 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL\n")
475 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL\n")
476 }
476 }
477 //
477 //
478 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TCODE_CTRL, 0x0909); // [Time Rx : Time Tx : Link error : Tick-out IRQ]
478 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TCODE_CTRL, 0x0909); // [Time Rx : Time Tx : Link error : Tick-out IRQ]
479 if (status!=RTEMS_SUCCESSFUL) {
479 if (status!=RTEMS_SUCCESSFUL) {
480 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TCODE_CTRL,\n")
480 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TCODE_CTRL,\n")
481 }
481 }
482
482
483 return status;
483 return status;
484 }
484 }
485
485
486 int spacewire_several_connect_attemps( void )
486 int spacewire_several_connect_attemps( void )
487 {
487 {
488 /** This function is executed by the SPIQ rtems_task wehn it has been awaken by an interruption raised by the SpaceWire driver.
488 /** This function is executed by the SPIQ rtems_task wehn it has been awaken by an interruption raised by the SpaceWire driver.
489 *
489 *
490 * @return RTEMS directive status code:
490 * @return RTEMS directive status code:
491 * - RTEMS_UNSATISFIED is returned is the link is not in the running state after 10 s.
491 * - RTEMS_UNSATISFIED is returned is the link is not in the running state after 10 s.
492 * - RTEMS_SUCCESSFUL is returned if the link is up before the timeout.
492 * - RTEMS_SUCCESSFUL is returned if the link is up before the timeout.
493 *
493 *
494 */
494 */
495
495
496 rtems_status_code status_spw;
496 rtems_status_code status_spw;
497 rtems_status_code status;
497 rtems_status_code status;
498 int i;
498 int i;
499
499
500 for ( i=0; i<SY_LFR_DPU_CONNECT_ATTEMPT; i++ )
500 for ( i=0; i<SY_LFR_DPU_CONNECT_ATTEMPT; i++ )
501 {
501 {
502 PRINTF1("in spacewire_reset_link *** link recovery, try %d\n", i);
502 PRINTF1("in spacewire_reset_link *** link recovery, try %d\n", i);
503
503
504 // CLOSING THE DRIVER AT THIS POINT WILL MAKE THE SEND TASK BLOCK THE SYSTEM
504 // CLOSING THE DRIVER AT THIS POINT WILL MAKE THE SEND TASK BLOCK THE SYSTEM
505
505
506 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
506 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
507
507
508 status_spw = spacewire_stop_and_start_link( fdSPW );
508 status_spw = spacewire_stop_and_start_link( fdSPW );
509
509
510 if ( status_spw != RTEMS_SUCCESSFUL )
510 if ( status_spw != RTEMS_SUCCESSFUL )
511 {
511 {
512 PRINTF1("in spacewire_reset_link *** ERR spacewire_start_link code %d\n", status_spw)
512 PRINTF1("in spacewire_reset_link *** ERR spacewire_start_link code %d\n", status_spw)
513 }
513 }
514
514
515 if ( status_spw == RTEMS_SUCCESSFUL)
515 if ( status_spw == RTEMS_SUCCESSFUL)
516 {
516 {
517 break;
517 break;
518 }
518 }
519 }
519 }
520
520
521 return status_spw;
521 return status_spw;
522 }
522 }
523
523
524 void spacewire_set_NP( unsigned char val, unsigned int regAddr ) // [N]o [P]ort force
524 void spacewire_set_NP( unsigned char val, unsigned int regAddr ) // [N]o [P]ort force
525 {
525 {
526 /** This function sets the [N]o [P]ort force bit of the GRSPW control register.
526 /** This function sets the [N]o [P]ort force bit of the GRSPW control register.
527 *
527 *
528 * @param val is the value, 0 or 1, used to set the value of the NP bit.
528 * @param val is the value, 0 or 1, used to set the value of the NP bit.
529 * @param regAddr is the address of the GRSPW control register.
529 * @param regAddr is the address of the GRSPW control register.
530 *
530 *
531 * NP is the bit 20 of the GRSPW control register.
531 * NP is the bit 20 of the GRSPW control register.
532 *
532 *
533 */
533 */
534
534
535 unsigned int *spwptr = (unsigned int*) regAddr;
535 unsigned int *spwptr = (unsigned int*) regAddr;
536
536
537 if (val == 1) {
537 if (val == 1) {
538 *spwptr = *spwptr | 0x00100000; // [NP] set the No port force bit
538 *spwptr = *spwptr | 0x00100000; // [NP] set the No port force bit
539 }
539 }
540 if (val== 0) {
540 if (val== 0) {
541 *spwptr = *spwptr & 0xffdfffff;
541 *spwptr = *spwptr & 0xffdfffff;
542 }
542 }
543 }
543 }
544
544
545 void spacewire_set_RE( unsigned char val, unsigned int regAddr ) // [R]MAP [E]nable
545 void spacewire_set_RE( unsigned char val, unsigned int regAddr ) // [R]MAP [E]nable
546 {
546 {
547 /** This function sets the [R]MAP [E]nable bit of the GRSPW control register.
547 /** This function sets the [R]MAP [E]nable bit of the GRSPW control register.
548 *
548 *
549 * @param val is the value, 0 or 1, used to set the value of the RE bit.
549 * @param val is the value, 0 or 1, used to set the value of the RE bit.
550 * @param regAddr is the address of the GRSPW control register.
550 * @param regAddr is the address of the GRSPW control register.
551 *
551 *
552 * RE is the bit 16 of the GRSPW control register.
552 * RE is the bit 16 of the GRSPW control register.
553 *
553 *
554 */
554 */
555
555
556 unsigned int *spwptr = (unsigned int*) regAddr;
556 unsigned int *spwptr = (unsigned int*) regAddr;
557
557
558 if (val == 1)
558 if (val == 1)
559 {
559 {
560 *spwptr = *spwptr | 0x00010000; // [RE] set the RMAP Enable bit
560 *spwptr = *spwptr | 0x00010000; // [RE] set the RMAP Enable bit
561 }
561 }
562 if (val== 0)
562 if (val== 0)
563 {
563 {
564 *spwptr = *spwptr & 0xfffdffff;
564 *spwptr = *spwptr & 0xfffdffff;
565 }
565 }
566 }
566 }
567
567
568 void spacewire_read_statistics( void )
568 void spacewire_read_statistics( void )
569 {
569 {
570 /** This function reads the SpaceWire statistics from the grspw RTEMS driver.
570 /** This function reads the SpaceWire statistics from the grspw RTEMS driver.
571 *
571 *
572 * @param void
572 * @param void
573 *
573 *
574 * @return void
574 * @return void
575 *
575 *
576 * Once they are read, the counters are stored in a global variable used during the building of the
576 * Once they are read, the counters are stored in a global variable used during the building of the
577 * HK packets.
577 * HK packets.
578 *
578 *
579 */
579 */
580
580
581 rtems_status_code status;
581 rtems_status_code status;
582 spw_stats current;
582 spw_stats current;
583
583
584 spacewire_get_last_error();
584 spacewire_get_last_error();
585
585
586 // read the current statistics
586 // read the current statistics
587 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &current );
587 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &current );
588
588
589 // clear the counters
589 // clear the counters
590 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_CLR_STATISTICS );
590 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_CLR_STATISTICS );
591
591
592 // typedef struct {
592 // typedef struct {
593 // unsigned int tx_link_err; // NOT IN HK
593 // unsigned int tx_link_err; // NOT IN HK
594 // unsigned int rx_rmap_header_crc_err; // NOT IN HK
594 // unsigned int rx_rmap_header_crc_err; // NOT IN HK
595 // unsigned int rx_rmap_data_crc_err; // NOT IN HK
595 // unsigned int rx_rmap_data_crc_err; // NOT IN HK
596 // unsigned int rx_eep_err;
596 // unsigned int rx_eep_err;
597 // unsigned int rx_truncated;
597 // unsigned int rx_truncated;
598 // unsigned int parity_err;
598 // unsigned int parity_err;
599 // unsigned int escape_err;
599 // unsigned int escape_err;
600 // unsigned int credit_err;
600 // unsigned int credit_err;
601 // unsigned int write_sync_err;
601 // unsigned int write_sync_err;
602 // unsigned int disconnect_err;
602 // unsigned int disconnect_err;
603 // unsigned int early_ep;
603 // unsigned int early_ep;
604 // unsigned int invalid_address;
604 // unsigned int invalid_address;
605 // unsigned int packets_sent;
605 // unsigned int packets_sent;
606 // unsigned int packets_received;
606 // unsigned int packets_received;
607 // } spw_stats;
607 // } spw_stats;
608
608
609 // rx_eep_err
609 // rx_eep_err
610 grspw_stats.rx_eep_err = grspw_stats.rx_eep_err + current.rx_eep_err;
610 grspw_stats.rx_eep_err = grspw_stats.rx_eep_err + current.rx_eep_err;
611 // rx_truncated
611 // rx_truncated
612 grspw_stats.rx_truncated = grspw_stats.rx_truncated + current.rx_truncated;
612 grspw_stats.rx_truncated = grspw_stats.rx_truncated + current.rx_truncated;
613 // parity_err
613 // parity_err
614 grspw_stats.parity_err = grspw_stats.parity_err + current.parity_err;
614 grspw_stats.parity_err = grspw_stats.parity_err + current.parity_err;
615 // escape_err
615 // escape_err
616 grspw_stats.escape_err = grspw_stats.escape_err + current.escape_err;
616 grspw_stats.escape_err = grspw_stats.escape_err + current.escape_err;
617 // credit_err
617 // credit_err
618 grspw_stats.credit_err = grspw_stats.credit_err + current.credit_err;
618 grspw_stats.credit_err = grspw_stats.credit_err + current.credit_err;
619 // write_sync_err
619 // write_sync_err
620 grspw_stats.write_sync_err = grspw_stats.write_sync_err + current.write_sync_err;
620 grspw_stats.write_sync_err = grspw_stats.write_sync_err + current.write_sync_err;
621 // disconnect_err
621 // disconnect_err
622 grspw_stats.disconnect_err = grspw_stats.disconnect_err + current.disconnect_err;
622 grspw_stats.disconnect_err = grspw_stats.disconnect_err + current.disconnect_err;
623 // early_ep
623 // early_ep
624 grspw_stats.early_ep = grspw_stats.early_ep + current.early_ep;
624 grspw_stats.early_ep = grspw_stats.early_ep + current.early_ep;
625 // invalid_address
625 // invalid_address
626 grspw_stats.invalid_address = grspw_stats.invalid_address + current.invalid_address;
626 grspw_stats.invalid_address = grspw_stats.invalid_address + current.invalid_address;
627 // packets_sent
627 // packets_sent
628 grspw_stats.packets_sent = grspw_stats.packets_sent + current.packets_sent;
628 grspw_stats.packets_sent = grspw_stats.packets_sent + current.packets_sent;
629 // packets_received
629 // packets_received
630 grspw_stats.packets_received= grspw_stats.packets_received + current.packets_received;
630 grspw_stats.packets_received= grspw_stats.packets_received + current.packets_received;
631
631
632 }
632 }
633
633
634 void spacewire_get_last_error( void )
634 void spacewire_get_last_error( void )
635 {
635 {
636 static spw_stats previous;
636 static spw_stats previous;
637 spw_stats current;
637 spw_stats current;
638 rtems_status_code status;
638 rtems_status_code status;
639
639
640 unsigned int hk_lfr_last_er_rid;
640 unsigned int hk_lfr_last_er_rid;
641 unsigned char hk_lfr_last_er_code;
641 unsigned char hk_lfr_last_er_code;
642 int coarseTime;
642 int coarseTime;
643 int fineTime;
643 int fineTime;
644 unsigned char update_hk_lfr_last_er;
644 unsigned char update_hk_lfr_last_er;
645
645
646 update_hk_lfr_last_er = 0;
646 update_hk_lfr_last_er = 0;
647
647
648 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &current );
648 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &current );
649
649
650 // get current time
650 // get current time
651 coarseTime = time_management_regs->coarse_time;
651 coarseTime = time_management_regs->coarse_time;
652 fineTime = time_management_regs->fine_time;
652 fineTime = time_management_regs->fine_time;
653
653
654 // typedef struct {
654 // typedef struct {
655 // unsigned int tx_link_err; // NOT IN HK
655 // unsigned int tx_link_err; // NOT IN HK
656 // unsigned int rx_rmap_header_crc_err; // NOT IN HK
656 // unsigned int rx_rmap_header_crc_err; // NOT IN HK
657 // unsigned int rx_rmap_data_crc_err; // NOT IN HK
657 // unsigned int rx_rmap_data_crc_err; // NOT IN HK
658 // unsigned int rx_eep_err;
658 // unsigned int rx_eep_err;
659 // unsigned int rx_truncated;
659 // unsigned int rx_truncated;
660 // unsigned int parity_err;
660 // unsigned int parity_err;
661 // unsigned int escape_err;
661 // unsigned int escape_err;
662 // unsigned int credit_err;
662 // unsigned int credit_err;
663 // unsigned int write_sync_err;
663 // unsigned int write_sync_err;
664 // unsigned int disconnect_err;
664 // unsigned int disconnect_err;
665 // unsigned int early_ep;
665 // unsigned int early_ep;
666 // unsigned int invalid_address;
666 // unsigned int invalid_address;
667 // unsigned int packets_sent;
667 // unsigned int packets_sent;
668 // unsigned int packets_received;
668 // unsigned int packets_received;
669 // } spw_stats;
669 // } spw_stats;
670
670
671 // tx_link_err *** no code associated to this field
671 // tx_link_err *** no code associated to this field
672 // rx_rmap_header_crc_err *** LE *** in HK
672 // rx_rmap_header_crc_err *** LE *** in HK
673 if (previous.rx_rmap_header_crc_err != current.rx_rmap_header_crc_err)
673 if (previous.rx_rmap_header_crc_err != current.rx_rmap_header_crc_err)
674 {
674 {
675 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
675 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
676 hk_lfr_last_er_code = CODE_HEADER_CRC;
676 hk_lfr_last_er_code = CODE_HEADER_CRC;
677 update_hk_lfr_last_er = 1;
677 update_hk_lfr_last_er = 1;
678 }
678 }
679 // rx_rmap_data_crc_err *** LE *** NOT IN HK
679 // rx_rmap_data_crc_err *** LE *** NOT IN HK
680 if (previous.rx_rmap_data_crc_err != current.rx_rmap_data_crc_err)
680 if (previous.rx_rmap_data_crc_err != current.rx_rmap_data_crc_err)
681 {
681 {
682 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
682 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
683 hk_lfr_last_er_code = CODE_DATA_CRC;
683 hk_lfr_last_er_code = CODE_DATA_CRC;
684 update_hk_lfr_last_er = 1;
684 update_hk_lfr_last_er = 1;
685 }
685 }
686 // rx_eep_err
686 // rx_eep_err
687 if (previous.rx_eep_err != current.rx_eep_err)
687 if (previous.rx_eep_err != current.rx_eep_err)
688 {
688 {
689 hk_lfr_last_er_rid = RID_ME_LFR_DPU_SPW;
689 hk_lfr_last_er_rid = RID_ME_LFR_DPU_SPW;
690 hk_lfr_last_er_code = CODE_EEP;
690 hk_lfr_last_er_code = CODE_EEP;
691 update_hk_lfr_last_er = 1;
691 update_hk_lfr_last_er = 1;
692 }
692 }
693 // rx_truncated
693 // rx_truncated
694 if (previous.rx_truncated != current.rx_truncated)
694 if (previous.rx_truncated != current.rx_truncated)
695 {
695 {
696 hk_lfr_last_er_rid = RID_ME_LFR_DPU_SPW;
696 hk_lfr_last_er_rid = RID_ME_LFR_DPU_SPW;
697 hk_lfr_last_er_code = CODE_RX_TOO_BIG;
697 hk_lfr_last_er_code = CODE_RX_TOO_BIG;
698 update_hk_lfr_last_er = 1;
698 update_hk_lfr_last_er = 1;
699 }
699 }
700 // parity_err
700 // parity_err
701 if (previous.parity_err != current.parity_err)
701 if (previous.parity_err != current.parity_err)
702 {
702 {
703 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
703 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
704 hk_lfr_last_er_code = CODE_PARITY;
704 hk_lfr_last_er_code = CODE_PARITY;
705 update_hk_lfr_last_er = 1;
705 update_hk_lfr_last_er = 1;
706 }
706 }
707 // escape_err
707 // escape_err
708 if (previous.parity_err != current.parity_err)
708 if (previous.parity_err != current.parity_err)
709 {
709 {
710 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
710 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
711 hk_lfr_last_er_code = CODE_ESCAPE;
711 hk_lfr_last_er_code = CODE_ESCAPE;
712 update_hk_lfr_last_er = 1;
712 update_hk_lfr_last_er = 1;
713 }
713 }
714 // credit_err
714 // credit_err
715 if (previous.credit_err != current.credit_err)
715 if (previous.credit_err != current.credit_err)
716 {
716 {
717 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
717 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
718 hk_lfr_last_er_code = CODE_CREDIT;
718 hk_lfr_last_er_code = CODE_CREDIT;
719 update_hk_lfr_last_er = 1;
719 update_hk_lfr_last_er = 1;
720 }
720 }
721 // write_sync_err
721 // write_sync_err
722 if (previous.write_sync_err != current.write_sync_err)
722 if (previous.write_sync_err != current.write_sync_err)
723 {
723 {
724 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
724 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
725 hk_lfr_last_er_code = CODE_WRITE_SYNC;
725 hk_lfr_last_er_code = CODE_WRITE_SYNC;
726 update_hk_lfr_last_er = 1;
726 update_hk_lfr_last_er = 1;
727 }
727 }
728 // disconnect_err
728 // disconnect_err
729 if (previous.disconnect_err != current.disconnect_err)
729 if (previous.disconnect_err != current.disconnect_err)
730 {
730 {
731 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
731 hk_lfr_last_er_rid = RID_LE_LFR_DPU_SPW;
732 hk_lfr_last_er_code = CODE_DISCONNECT;
732 hk_lfr_last_er_code = CODE_DISCONNECT;
733 update_hk_lfr_last_er = 1;
733 update_hk_lfr_last_er = 1;
734 }
734 }
735 // early_ep
735 // early_ep
736 if (previous.early_ep != current.early_ep)
736 if (previous.early_ep != current.early_ep)
737 {
737 {
738 hk_lfr_last_er_rid = RID_ME_LFR_DPU_SPW;
738 hk_lfr_last_er_rid = RID_ME_LFR_DPU_SPW;
739 hk_lfr_last_er_code = CODE_EARLY_EOP_EEP;
739 hk_lfr_last_er_code = CODE_EARLY_EOP_EEP;
740 update_hk_lfr_last_er = 1;
740 update_hk_lfr_last_er = 1;
741 }
741 }
742 // invalid_address
742 // invalid_address
743 if (previous.invalid_address != current.invalid_address)
743 if (previous.invalid_address != current.invalid_address)
744 {
744 {
745 hk_lfr_last_er_rid = RID_ME_LFR_DPU_SPW;
745 hk_lfr_last_er_rid = RID_ME_LFR_DPU_SPW;
746 hk_lfr_last_er_code = CODE_INVALID_ADDRESS;
746 hk_lfr_last_er_code = CODE_INVALID_ADDRESS;
747 update_hk_lfr_last_er = 1;
747 update_hk_lfr_last_er = 1;
748 }
748 }
749
749
750 // if a field has changed, update the hk_last_er fields
750 // if a field has changed, update the hk_last_er fields
751 if (update_hk_lfr_last_er == 1)
751 if (update_hk_lfr_last_er == 1)
752 {
752 {
753 update_hk_lfr_last_er_fields( hk_lfr_last_er_rid, hk_lfr_last_er_code );
753 update_hk_lfr_last_er_fields( hk_lfr_last_er_rid, hk_lfr_last_er_code );
754 }
754 }
755
755
756 previous = current;
756 previous = current;
757 }
757 }
758
758
759 void update_hk_lfr_last_er_fields(unsigned int rid, unsigned char code)
759 void update_hk_lfr_last_er_fields(unsigned int rid, unsigned char code)
760 {
760 {
761 unsigned char *coarseTimePtr;
761 unsigned char *coarseTimePtr;
762 unsigned char *fineTimePtr;
762 unsigned char *fineTimePtr;
763
763
764 coarseTimePtr = (unsigned char*) &time_management_regs->coarse_time;
764 coarseTimePtr = (unsigned char*) &time_management_regs->coarse_time;
765 fineTimePtr = (unsigned char*) &time_management_regs->fine_time;
765 fineTimePtr = (unsigned char*) &time_management_regs->fine_time;
766
766
767 housekeeping_packet.hk_lfr_last_er_rid[0] = (unsigned char) ((rid & 0xff00) >> 8 );
767 housekeeping_packet.hk_lfr_last_er_rid[0] = (unsigned char) ((rid & 0xff00) >> 8 );
768 housekeeping_packet.hk_lfr_last_er_rid[1] = (unsigned char) (rid & 0x00ff);
768 housekeeping_packet.hk_lfr_last_er_rid[1] = (unsigned char) (rid & 0x00ff);
769 housekeeping_packet.hk_lfr_last_er_code = code;
769 housekeeping_packet.hk_lfr_last_er_code = code;
770 housekeeping_packet.hk_lfr_last_er_time[0] = coarseTimePtr[0];
770 housekeeping_packet.hk_lfr_last_er_time[0] = coarseTimePtr[0];
771 housekeeping_packet.hk_lfr_last_er_time[1] = coarseTimePtr[1];
771 housekeeping_packet.hk_lfr_last_er_time[1] = coarseTimePtr[1];
772 housekeeping_packet.hk_lfr_last_er_time[2] = coarseTimePtr[2];
772 housekeeping_packet.hk_lfr_last_er_time[2] = coarseTimePtr[2];
773 housekeeping_packet.hk_lfr_last_er_time[3] = coarseTimePtr[3];
773 housekeeping_packet.hk_lfr_last_er_time[3] = coarseTimePtr[3];
774 housekeeping_packet.hk_lfr_last_er_time[4] = fineTimePtr[2];
774 housekeeping_packet.hk_lfr_last_er_time[4] = fineTimePtr[2];
775 housekeeping_packet.hk_lfr_last_er_time[5] = fineTimePtr[3];
775 housekeeping_packet.hk_lfr_last_er_time[5] = fineTimePtr[3];
776 }
776 }
777
777
778 void update_hk_with_grspw_stats( void )
778 void update_hk_with_grspw_stats( void )
779 {
779 {
780 //****************************
780 //****************************
781 // DPU_SPACEWIRE_IF_STATISTICS
781 // DPU_SPACEWIRE_IF_STATISTICS
782 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[0] = (unsigned char) (grspw_stats.packets_received >> 8);
782 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[0] = (unsigned char) (grspw_stats.packets_received >> 8);
783 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[1] = (unsigned char) (grspw_stats.packets_received);
783 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[1] = (unsigned char) (grspw_stats.packets_received);
784 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[0] = (unsigned char) (grspw_stats.packets_sent >> 8);
784 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[0] = (unsigned char) (grspw_stats.packets_sent >> 8);
785 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[1] = (unsigned char) (grspw_stats.packets_sent);
785 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[1] = (unsigned char) (grspw_stats.packets_sent);
786
786
787 //******************************************
787 //******************************************
788 // ERROR COUNTERS / SPACEWIRE / LOW SEVERITY
788 // ERROR COUNTERS / SPACEWIRE / LOW SEVERITY
789 housekeeping_packet.hk_lfr_dpu_spw_parity = (unsigned char) grspw_stats.parity_err;
789 housekeeping_packet.hk_lfr_dpu_spw_parity = (unsigned char) grspw_stats.parity_err;
790 housekeeping_packet.hk_lfr_dpu_spw_disconnect = (unsigned char) grspw_stats.disconnect_err;
790 housekeeping_packet.hk_lfr_dpu_spw_disconnect = (unsigned char) grspw_stats.disconnect_err;
791 housekeeping_packet.hk_lfr_dpu_spw_escape = (unsigned char) grspw_stats.escape_err;
791 housekeeping_packet.hk_lfr_dpu_spw_escape = (unsigned char) grspw_stats.escape_err;
792 housekeeping_packet.hk_lfr_dpu_spw_credit = (unsigned char) grspw_stats.credit_err;
792 housekeeping_packet.hk_lfr_dpu_spw_credit = (unsigned char) grspw_stats.credit_err;
793 housekeeping_packet.hk_lfr_dpu_spw_write_sync = (unsigned char) grspw_stats.write_sync_err;
793 housekeeping_packet.hk_lfr_dpu_spw_write_sync = (unsigned char) grspw_stats.write_sync_err;
794
794
795 //*********************************************
795 //*********************************************
796 // ERROR COUNTERS / SPACEWIRE / MEDIUM SEVERITY
796 // ERROR COUNTERS / SPACEWIRE / MEDIUM SEVERITY
797 housekeeping_packet.hk_lfr_dpu_spw_early_eop = (unsigned char) grspw_stats.early_ep;
797 housekeeping_packet.hk_lfr_dpu_spw_early_eop = (unsigned char) grspw_stats.early_ep;
798 housekeeping_packet.hk_lfr_dpu_spw_invalid_addr = (unsigned char) grspw_stats.invalid_address;
798 housekeeping_packet.hk_lfr_dpu_spw_invalid_addr = (unsigned char) grspw_stats.invalid_address;
799 housekeeping_packet.hk_lfr_dpu_spw_eep = (unsigned char) grspw_stats.rx_eep_err;
799 housekeeping_packet.hk_lfr_dpu_spw_eep = (unsigned char) grspw_stats.rx_eep_err;
800 housekeeping_packet.hk_lfr_dpu_spw_rx_too_big = (unsigned char) grspw_stats.rx_truncated;
800 housekeeping_packet.hk_lfr_dpu_spw_rx_too_big = (unsigned char) grspw_stats.rx_truncated;
801 }
801 }
802
802
803 void spacewire_update_hk_lfr_link_state( unsigned char *hk_lfr_status_word_0 )
804 {
805 unsigned int *statusRegisterPtr;
806 unsigned char linkState;
807
808 statusRegisterPtr = (unsigned int *) (REGS_ADDR_GRSPW + APB_OFFSET_GRSPW_STATUS_REGISTER);
809 linkState = (unsigned char) ( ( (*statusRegisterPtr) >> 21) & 0x07); // [0000 0111]
810
811 *hk_lfr_status_word_0 = *hk_lfr_status_word_0 & 0xf8; // [1111 1000] set link state to 0
812
813 *hk_lfr_status_word_0 = *hk_lfr_status_word_0 | linkState; // update hk_lfr_dpu_spw_link_state
814 }
815
803 void increase_unsigned_char_counter( unsigned char *counter )
816 void increase_unsigned_char_counter( unsigned char *counter )
804 {
817 {
805 // update the number of valid timecodes that have been received
818 // update the number of valid timecodes that have been received
806 if (*counter == 255)
819 if (*counter == 255)
807 {
820 {
808 *counter = 0;
821 *counter = 0;
809 }
822 }
810 else
823 else
811 {
824 {
812 *counter = *counter + 1;
825 *counter = *counter + 1;
813 }
826 }
814 }
827 }
815
828
816 unsigned int check_timecode_and_previous_timecode_coherency(unsigned char currentTimecodeCtr)
829 unsigned int check_timecode_and_previous_timecode_coherency(unsigned char currentTimecodeCtr)
817 {
830 {
818 /** This function checks the coherency between the incoming timecode and the last valid timecode.
831 /** This function checks the coherency between the incoming timecode and the last valid timecode.
819 *
832 *
820 * @param currentTimecodeCtr is the incoming timecode
833 * @param currentTimecodeCtr is the incoming timecode
821 *
834 *
822 * @return returned codes::
835 * @return returned codes::
823 * - LFR_DEFAULT
836 * - LFR_DEFAULT
824 * - LFR_SUCCESSFUL
837 * - LFR_SUCCESSFUL
825 *
838 *
826 */
839 */
827
840
828 static unsigned char firstTickout = 1;
841 static unsigned char firstTickout = 1;
829 unsigned char ret;
842 unsigned char ret;
830
843
831 ret = LFR_DEFAULT;
844 ret = LFR_DEFAULT;
832
845
833 if (firstTickout == 0)
846 if (firstTickout == 0)
834 {
847 {
835 if (currentTimecodeCtr == 0)
848 if (currentTimecodeCtr == 0)
836 {
849 {
837 if (previousTimecodeCtr == 63)
850 if (previousTimecodeCtr == 63)
838 {
851 {
839 ret = LFR_SUCCESSFUL;
852 ret = LFR_SUCCESSFUL;
840 }
853 }
841 else
854 else
842 {
855 {
843 ret = LFR_DEFAULT;
856 ret = LFR_DEFAULT;
844 }
857 }
845 }
858 }
846 else
859 else
847 {
860 {
848 if (currentTimecodeCtr == (previousTimecodeCtr +1))
861 if (currentTimecodeCtr == (previousTimecodeCtr +1))
849 {
862 {
850 ret = LFR_SUCCESSFUL;
863 ret = LFR_SUCCESSFUL;
851 }
864 }
852 else
865 else
853 {
866 {
854 ret = LFR_DEFAULT;
867 ret = LFR_DEFAULT;
855 }
868 }
856 }
869 }
857 }
870 }
858 else
871 else
859 {
872 {
860 firstTickout = 0;
873 firstTickout = 0;
861 ret = LFR_SUCCESSFUL;
874 ret = LFR_SUCCESSFUL;
862 }
875 }
863
876
864 return ret;
877 return ret;
865 }
878 }
866
879
867 unsigned int check_timecode_and_internal_time_coherency(unsigned char timecode, unsigned char internalTime)
880 unsigned int check_timecode_and_internal_time_coherency(unsigned char timecode, unsigned char internalTime)
868 {
881 {
869 unsigned int ret;
882 unsigned int ret;
870
883
871 ret = LFR_DEFAULT;
884 ret = LFR_DEFAULT;
872
885
873 if (timecode == internalTime)
886 if (timecode == internalTime)
874 {
887 {
875 ret = LFR_SUCCESSFUL;
888 ret = LFR_SUCCESSFUL;
876 }
889 }
877 else
890 else
878 {
891 {
879 ret = LFR_DEFAULT;
892 ret = LFR_DEFAULT;
880 }
893 }
881
894
882 return ret;
895 return ret;
883 }
896 }
884
897
885 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc )
898 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc )
886 {
899 {
887 // a tickout has been emitted, perform actions on the incoming timecode
900 // a tickout has been emitted, perform actions on the incoming timecode
888
901
889 unsigned char incomingTimecode;
902 unsigned char incomingTimecode;
890 unsigned char updateTime;
903 unsigned char updateTime;
891 unsigned char internalTime;
904 unsigned char internalTime;
892 rtems_status_code status;
905 rtems_status_code status;
893
906
894 incomingTimecode = (unsigned char) (grspwPtr[0] & TIMECODE_MASK);
907 incomingTimecode = (unsigned char) (grspwPtr[0] & TIMECODE_MASK);
895 updateTime = time_management_regs->coarse_time_load & TIMECODE_MASK;
908 updateTime = time_management_regs->coarse_time_load & TIMECODE_MASK;
896 internalTime = time_management_regs->coarse_time & TIMECODE_MASK;
909 internalTime = time_management_regs->coarse_time & TIMECODE_MASK;
897
910
898 housekeeping_packet.hk_lfr_dpu_spw_last_timc = incomingTimecode;
911 housekeeping_packet.hk_lfr_dpu_spw_last_timc = incomingTimecode;
899
912
900 // update the number of tickout that have been generated
913 // update the number of tickout that have been generated
901 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt );
914 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt );
902
915
903 //**************************
916 //**************************
904 // HK_LFR_TIMECODE_ERRONEOUS
917 // HK_LFR_TIMECODE_ERRONEOUS
905 // MISSING and INVALID are handled by the timecode_timer_routine service routine
918 // MISSING and INVALID are handled by the timecode_timer_routine service routine
906 if (check_timecode_and_previous_timecode_coherency( incomingTimecode ) == LFR_DEFAULT)
919 if (check_timecode_and_previous_timecode_coherency( incomingTimecode ) == LFR_DEFAULT)
907 {
920 {
908 // this is unexpected but a tickout could have been raised despite of the timecode being erroneous
921 // this is unexpected but a tickout could have been raised despite of the timecode being erroneous
909 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_erroneous );
922 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_erroneous );
910 update_hk_lfr_last_er_fields( RID_LE_LFR_TIMEC, CODE_ERRONEOUS );
923 update_hk_lfr_last_er_fields( RID_LE_LFR_TIMEC, CODE_ERRONEOUS );
911 }
924 }
912
925
913 //************************
926 //************************
914 // HK_LFR_TIME_TIMECODE_IT
927 // HK_LFR_TIME_TIMECODE_IT
915 // check the coherency between the SpaceWire timecode and the Internal Time
928 // check the coherency between the SpaceWire timecode and the Internal Time
916 if (check_timecode_and_internal_time_coherency( incomingTimecode, internalTime ) == LFR_DEFAULT)
929 if (check_timecode_and_internal_time_coherency( incomingTimecode, internalTime ) == LFR_DEFAULT)
917 {
930 {
918 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_time_timecode_it );
931 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_time_timecode_it );
919 update_hk_lfr_last_er_fields( RID_LE_LFR_TIME, CODE_TIMECODE_IT );
932 update_hk_lfr_last_er_fields( RID_LE_LFR_TIME, CODE_TIMECODE_IT );
920 }
933 }
921
934
922 //********************
935 //********************
923 // HK_LFR_TIMECODE_CTR
936 // HK_LFR_TIMECODE_CTR
924 // check the value of the timecode with respect to the last TC_LFR_UPDATE_TIME => SSS-CP-FS-370
937 // check the value of the timecode with respect to the last TC_LFR_UPDATE_TIME => SSS-CP-FS-370
925 if (oneTcLfrUpdateTimeReceived == 1)
938 if (oneTcLfrUpdateTimeReceived == 1)
926 {
939 {
927 if ( incomingTimecode != updateTime )
940 if ( incomingTimecode != updateTime )
928 {
941 {
929 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_time_timecode_ctr );
942 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_time_timecode_ctr );
930 update_hk_lfr_last_er_fields( RID_LE_LFR_TIME, CODE_TIMECODE_CTR );
943 update_hk_lfr_last_er_fields( RID_LE_LFR_TIME, CODE_TIMECODE_CTR );
931 }
944 }
932 }
945 }
933
946
934 // launch the timecode timer to detect missing or invalid timecodes
947 // launch the timecode timer to detect missing or invalid timecodes
935 previousTimecodeCtr = incomingTimecode; // update the previousTimecodeCtr value
948 previousTimecodeCtr = incomingTimecode; // update the previousTimecodeCtr value
936 status = rtems_timer_fire_after( timecode_timer_id, TIMECODE_TIMER_TIMEOUT, timecode_timer_routine, NULL );
949 status = rtems_timer_fire_after( timecode_timer_id, TIMECODE_TIMER_TIMEOUT, timecode_timer_routine, NULL );
937 if (status != RTEMS_SUCCESSFUL)
950 if (status != RTEMS_SUCCESSFUL)
938 {
951 {
939 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_14 );
952 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_14 );
940 }
953 }
941 }
954 }
942
955
943 rtems_timer_service_routine timecode_timer_routine( rtems_id timer_id, void *user_data )
956 rtems_timer_service_routine timecode_timer_routine( rtems_id timer_id, void *user_data )
944 {
957 {
945 static unsigned char initStep = 1;
958 static unsigned char initStep = 1;
946
959
947 unsigned char currentTimecodeCtr;
960 unsigned char currentTimecodeCtr;
948
961
949 currentTimecodeCtr = (unsigned char) (grspwPtr[0] & TIMECODE_MASK);
962 currentTimecodeCtr = (unsigned char) (grspwPtr[0] & TIMECODE_MASK);
950
963
951 if (initStep == 1)
964 if (initStep == 1)
952 {
965 {
953 if (currentTimecodeCtr == previousTimecodeCtr)
966 if (currentTimecodeCtr == previousTimecodeCtr)
954 {
967 {
955 //************************
968 //************************
956 // HK_LFR_TIMECODE_MISSING
969 // HK_LFR_TIMECODE_MISSING
957 // the timecode value has not changed, no valid timecode has been received, the timecode is MISSING
970 // the timecode value has not changed, no valid timecode has been received, the timecode is MISSING
958 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_missing );
971 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_missing );
959 update_hk_lfr_last_er_fields( RID_LE_LFR_TIMEC, CODE_MISSING );
972 update_hk_lfr_last_er_fields( RID_LE_LFR_TIMEC, CODE_MISSING );
960 }
973 }
961 else if (currentTimecodeCtr == (previousTimecodeCtr+1))
974 else if (currentTimecodeCtr == (previousTimecodeCtr+1))
962 {
975 {
963 // the timecode value has changed and the value is valid, this is unexpected because
976 // the timecode value has changed and the value is valid, this is unexpected because
964 // the timer should not have fired, the timecode_irq_handler should have been raised
977 // the timer should not have fired, the timecode_irq_handler should have been raised
965 }
978 }
966 else
979 else
967 {
980 {
968 //************************
981 //************************
969 // HK_LFR_TIMECODE_INVALID
982 // HK_LFR_TIMECODE_INVALID
970 // the timecode value has changed and the value is not valid, no tickout has been generated
983 // the timecode value has changed and the value is not valid, no tickout has been generated
971 // this is why the timer has fired
984 // this is why the timer has fired
972 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_invalid );
985 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_invalid );
973 update_hk_lfr_last_er_fields( RID_LE_LFR_TIMEC, CODE_INVALID );
986 update_hk_lfr_last_er_fields( RID_LE_LFR_TIMEC, CODE_INVALID );
974 }
987 }
975 }
988 }
976 else
989 else
977 {
990 {
978 initStep = 1;
991 initStep = 1;
979 //************************
992 //************************
980 // HK_LFR_TIMECODE_MISSING
993 // HK_LFR_TIMECODE_MISSING
981 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_missing );
994 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_missing );
982 update_hk_lfr_last_er_fields( RID_LE_LFR_TIMEC, CODE_MISSING );
995 update_hk_lfr_last_er_fields( RID_LE_LFR_TIMEC, CODE_MISSING );
983 }
996 }
984
997
985 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_13 );
998 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_13 );
986 }
999 }
987
1000
988 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header )
1001 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header )
989 {
1002 {
990 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
1003 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
991 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
1004 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
992 header->reserved = DEFAULT_RESERVED;
1005 header->reserved = DEFAULT_RESERVED;
993 header->userApplication = CCSDS_USER_APP;
1006 header->userApplication = CCSDS_USER_APP;
994 header->packetSequenceControl[0]= TM_PACKET_SEQ_CTRL_STANDALONE;
1007 header->packetSequenceControl[0]= TM_PACKET_SEQ_CTRL_STANDALONE;
995 header->packetSequenceControl[1]= TM_PACKET_SEQ_CNT_DEFAULT;
1008 header->packetSequenceControl[1]= TM_PACKET_SEQ_CNT_DEFAULT;
996 header->packetLength[0] = 0x00;
1009 header->packetLength[0] = 0x00;
997 header->packetLength[1] = 0x00;
1010 header->packetLength[1] = 0x00;
998 // DATA FIELD HEADER
1011 // DATA FIELD HEADER
999 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
1012 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
1000 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
1013 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
1001 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6; // service subtype
1014 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6; // service subtype
1002 header->destinationID = TM_DESTINATION_ID_GROUND;
1015 header->destinationID = TM_DESTINATION_ID_GROUND;
1003 header->time[0] = 0x00;
1016 header->time[0] = 0x00;
1004 header->time[0] = 0x00;
1017 header->time[0] = 0x00;
1005 header->time[0] = 0x00;
1018 header->time[0] = 0x00;
1006 header->time[0] = 0x00;
1019 header->time[0] = 0x00;
1007 header->time[0] = 0x00;
1020 header->time[0] = 0x00;
1008 header->time[0] = 0x00;
1021 header->time[0] = 0x00;
1009 // AUXILIARY DATA HEADER
1022 // AUXILIARY DATA HEADER
1010 header->sid = 0x00;
1023 header->sid = 0x00;
1011 header->hkBIA = DEFAULT_HKBIA;
1024 header->hkBIA = DEFAULT_HKBIA;
1012 header->blkNr[0] = 0x00;
1025 header->blkNr[0] = 0x00;
1013 header->blkNr[1] = 0x00;
1026 header->blkNr[1] = 0x00;
1014 }
1027 }
1015
1028
1016 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header )
1029 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header )
1017 {
1030 {
1018 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
1031 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
1019 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
1032 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
1020 header->reserved = DEFAULT_RESERVED;
1033 header->reserved = DEFAULT_RESERVED;
1021 header->userApplication = CCSDS_USER_APP;
1034 header->userApplication = CCSDS_USER_APP;
1022 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1035 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1023 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1036 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1024 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
1037 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
1025 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
1038 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
1026 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
1039 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
1027 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
1040 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
1028 // DATA FIELD HEADER
1041 // DATA FIELD HEADER
1029 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
1042 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
1030 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
1043 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
1031 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6; // service subtype
1044 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6; // service subtype
1032 header->destinationID = TM_DESTINATION_ID_GROUND;
1045 header->destinationID = TM_DESTINATION_ID_GROUND;
1033 header->time[0] = 0x00;
1046 header->time[0] = 0x00;
1034 header->time[0] = 0x00;
1047 header->time[0] = 0x00;
1035 header->time[0] = 0x00;
1048 header->time[0] = 0x00;
1036 header->time[0] = 0x00;
1049 header->time[0] = 0x00;
1037 header->time[0] = 0x00;
1050 header->time[0] = 0x00;
1038 header->time[0] = 0x00;
1051 header->time[0] = 0x00;
1039 // AUXILIARY DATA HEADER
1052 // AUXILIARY DATA HEADER
1040 header->sid = 0x00;
1053 header->sid = 0x00;
1041 header->hkBIA = DEFAULT_HKBIA;
1054 header->hkBIA = DEFAULT_HKBIA;
1042 header->pktCnt = DEFAULT_PKTCNT; // PKT_CNT
1055 header->pktCnt = DEFAULT_PKTCNT; // PKT_CNT
1043 header->pktNr = 0x00;
1056 header->pktNr = 0x00;
1044 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
1057 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
1045 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
1058 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
1046 }
1059 }
1047
1060
1048 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header )
1061 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header )
1049 {
1062 {
1050 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
1063 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
1051 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
1064 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
1052 header->reserved = DEFAULT_RESERVED;
1065 header->reserved = DEFAULT_RESERVED;
1053 header->userApplication = CCSDS_USER_APP;
1066 header->userApplication = CCSDS_USER_APP;
1054 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1067 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1055 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1068 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1056 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
1069 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
1057 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
1070 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
1058 header->packetLength[0] = 0x00;
1071 header->packetLength[0] = 0x00;
1059 header->packetLength[1] = 0x00;
1072 header->packetLength[1] = 0x00;
1060 // DATA FIELD HEADER
1073 // DATA FIELD HEADER
1061 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
1074 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
1062 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
1075 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
1063 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3; // service subtype
1076 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3; // service subtype
1064 header->destinationID = TM_DESTINATION_ID_GROUND;
1077 header->destinationID = TM_DESTINATION_ID_GROUND;
1065 header->time[0] = 0x00;
1078 header->time[0] = 0x00;
1066 header->time[0] = 0x00;
1079 header->time[0] = 0x00;
1067 header->time[0] = 0x00;
1080 header->time[0] = 0x00;
1068 header->time[0] = 0x00;
1081 header->time[0] = 0x00;
1069 header->time[0] = 0x00;
1082 header->time[0] = 0x00;
1070 header->time[0] = 0x00;
1083 header->time[0] = 0x00;
1071 // AUXILIARY DATA HEADER
1084 // AUXILIARY DATA HEADER
1072 header->sid = 0x00;
1085 header->sid = 0x00;
1073 header->biaStatusInfo = 0x00;
1086 header->biaStatusInfo = 0x00;
1074 header->pa_lfr_pkt_cnt_asm = 0x00;
1087 header->pa_lfr_pkt_cnt_asm = 0x00;
1075 header->pa_lfr_pkt_nr_asm = 0x00;
1088 header->pa_lfr_pkt_nr_asm = 0x00;
1076 header->pa_lfr_asm_blk_nr[0] = 0x00;
1089 header->pa_lfr_asm_blk_nr[0] = 0x00;
1077 header->pa_lfr_asm_blk_nr[1] = 0x00;
1090 header->pa_lfr_asm_blk_nr[1] = 0x00;
1078 }
1091 }
1079
1092
1080 int spw_send_waveform_CWF( ring_node *ring_node_to_send,
1093 int spw_send_waveform_CWF( ring_node *ring_node_to_send,
1081 Header_TM_LFR_SCIENCE_CWF_t *header )
1094 Header_TM_LFR_SCIENCE_CWF_t *header )
1082 {
1095 {
1083 /** This function sends CWF CCSDS packets (F2, F1 or F0).
1096 /** This function sends CWF CCSDS packets (F2, F1 or F0).
1084 *
1097 *
1085 * @param waveform points to the buffer containing the data that will be send.
1098 * @param waveform points to the buffer containing the data that will be send.
1086 * @param sid is the source identifier of the data that will be sent.
1099 * @param sid is the source identifier of the data that will be sent.
1087 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
1100 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
1088 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
1101 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
1089 * contain information to setup the transmission of the data packets.
1102 * contain information to setup the transmission of the data packets.
1090 *
1103 *
1091 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
1104 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
1092 *
1105 *
1093 */
1106 */
1094
1107
1095 unsigned int i;
1108 unsigned int i;
1096 int ret;
1109 int ret;
1097 unsigned int coarseTime;
1110 unsigned int coarseTime;
1098 unsigned int fineTime;
1111 unsigned int fineTime;
1099 rtems_status_code status;
1112 rtems_status_code status;
1100 spw_ioctl_pkt_send spw_ioctl_send_CWF;
1113 spw_ioctl_pkt_send spw_ioctl_send_CWF;
1101 int *dataPtr;
1114 int *dataPtr;
1102 unsigned char sid;
1115 unsigned char sid;
1103
1116
1104 spw_ioctl_send_CWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_CWF;
1117 spw_ioctl_send_CWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_CWF;
1105 spw_ioctl_send_CWF.options = 0;
1118 spw_ioctl_send_CWF.options = 0;
1106
1119
1107 ret = LFR_DEFAULT;
1120 ret = LFR_DEFAULT;
1108 sid = (unsigned char) ring_node_to_send->sid;
1121 sid = (unsigned char) ring_node_to_send->sid;
1109
1122
1110 coarseTime = ring_node_to_send->coarseTime;
1123 coarseTime = ring_node_to_send->coarseTime;
1111 fineTime = ring_node_to_send->fineTime;
1124 fineTime = ring_node_to_send->fineTime;
1112 dataPtr = (int*) ring_node_to_send->buffer_address;
1125 dataPtr = (int*) ring_node_to_send->buffer_address;
1113
1126
1114 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
1127 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
1115 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
1128 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
1116 header->hkBIA = pa_bia_status_info;
1129 header->hkBIA = pa_bia_status_info;
1117 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1130 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1118 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
1131 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
1119 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
1132 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
1120
1133
1121 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF; i++) // send waveform
1134 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF; i++) // send waveform
1122 {
1135 {
1123 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF * NB_WORDS_SWF_BLK) ];
1136 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF * NB_WORDS_SWF_BLK) ];
1124 spw_ioctl_send_CWF.hdr = (char*) header;
1137 spw_ioctl_send_CWF.hdr = (char*) header;
1125 // BUILD THE DATA
1138 // BUILD THE DATA
1126 spw_ioctl_send_CWF.dlen = BLK_NR_CWF * NB_BYTES_SWF_BLK;
1139 spw_ioctl_send_CWF.dlen = BLK_NR_CWF * NB_BYTES_SWF_BLK;
1127
1140
1128 // SET PACKET SEQUENCE CONTROL
1141 // SET PACKET SEQUENCE CONTROL
1129 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1142 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1130
1143
1131 // SET SID
1144 // SET SID
1132 header->sid = sid;
1145 header->sid = sid;
1133
1146
1134 // SET PACKET TIME
1147 // SET PACKET TIME
1135 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime);
1148 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime);
1136 //
1149 //
1137 header->time[0] = header->acquisitionTime[0];
1150 header->time[0] = header->acquisitionTime[0];
1138 header->time[1] = header->acquisitionTime[1];
1151 header->time[1] = header->acquisitionTime[1];
1139 header->time[2] = header->acquisitionTime[2];
1152 header->time[2] = header->acquisitionTime[2];
1140 header->time[3] = header->acquisitionTime[3];
1153 header->time[3] = header->acquisitionTime[3];
1141 header->time[4] = header->acquisitionTime[4];
1154 header->time[4] = header->acquisitionTime[4];
1142 header->time[5] = header->acquisitionTime[5];
1155 header->time[5] = header->acquisitionTime[5];
1143
1156
1144 // SET PACKET ID
1157 // SET PACKET ID
1145 if ( (sid == SID_SBM1_CWF_F1) || (sid == SID_SBM2_CWF_F2) )
1158 if ( (sid == SID_SBM1_CWF_F1) || (sid == SID_SBM2_CWF_F2) )
1146 {
1159 {
1147 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2 >> 8);
1160 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2 >> 8);
1148 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2);
1161 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2);
1149 }
1162 }
1150 else
1163 else
1151 {
1164 {
1152 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1165 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1153 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1166 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1154 }
1167 }
1155
1168
1156 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
1169 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
1157 if (status != RTEMS_SUCCESSFUL) {
1170 if (status != RTEMS_SUCCESSFUL) {
1158 ret = LFR_DEFAULT;
1171 ret = LFR_DEFAULT;
1159 }
1172 }
1160 }
1173 }
1161
1174
1162 return ret;
1175 return ret;
1163 }
1176 }
1164
1177
1165 int spw_send_waveform_SWF( ring_node *ring_node_to_send,
1178 int spw_send_waveform_SWF( ring_node *ring_node_to_send,
1166 Header_TM_LFR_SCIENCE_SWF_t *header )
1179 Header_TM_LFR_SCIENCE_SWF_t *header )
1167 {
1180 {
1168 /** This function sends SWF CCSDS packets (F2, F1 or F0).
1181 /** This function sends SWF CCSDS packets (F2, F1 or F0).
1169 *
1182 *
1170 * @param waveform points to the buffer containing the data that will be send.
1183 * @param waveform points to the buffer containing the data that will be send.
1171 * @param sid is the source identifier of the data that will be sent.
1184 * @param sid is the source identifier of the data that will be sent.
1172 * @param headerSWF points to a table of headers that have been prepared for the data transmission.
1185 * @param headerSWF points to a table of headers that have been prepared for the data transmission.
1173 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
1186 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
1174 * contain information to setup the transmission of the data packets.
1187 * contain information to setup the transmission of the data packets.
1175 *
1188 *
1176 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
1189 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
1177 *
1190 *
1178 */
1191 */
1179
1192
1180 unsigned int i;
1193 unsigned int i;
1181 int ret;
1194 int ret;
1182 unsigned int coarseTime;
1195 unsigned int coarseTime;
1183 unsigned int fineTime;
1196 unsigned int fineTime;
1184 rtems_status_code status;
1197 rtems_status_code status;
1185 spw_ioctl_pkt_send spw_ioctl_send_SWF;
1198 spw_ioctl_pkt_send spw_ioctl_send_SWF;
1186 int *dataPtr;
1199 int *dataPtr;
1187 unsigned char sid;
1200 unsigned char sid;
1188
1201
1189 spw_ioctl_send_SWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_SWF;
1202 spw_ioctl_send_SWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_SWF;
1190 spw_ioctl_send_SWF.options = 0;
1203 spw_ioctl_send_SWF.options = 0;
1191
1204
1192 ret = LFR_DEFAULT;
1205 ret = LFR_DEFAULT;
1193
1206
1194 coarseTime = ring_node_to_send->coarseTime;
1207 coarseTime = ring_node_to_send->coarseTime;
1195 fineTime = ring_node_to_send->fineTime;
1208 fineTime = ring_node_to_send->fineTime;
1196 dataPtr = (int*) ring_node_to_send->buffer_address;
1209 dataPtr = (int*) ring_node_to_send->buffer_address;
1197 sid = ring_node_to_send->sid;
1210 sid = ring_node_to_send->sid;
1198
1211
1199 header->hkBIA = pa_bia_status_info;
1212 header->hkBIA = pa_bia_status_info;
1200 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1213 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1201
1214
1202 for (i=0; i<7; i++) // send waveform
1215 for (i=0; i<7; i++) // send waveform
1203 {
1216 {
1204 spw_ioctl_send_SWF.data = (char*) &dataPtr[ (i * BLK_NR_304 * NB_WORDS_SWF_BLK) ];
1217 spw_ioctl_send_SWF.data = (char*) &dataPtr[ (i * BLK_NR_304 * NB_WORDS_SWF_BLK) ];
1205 spw_ioctl_send_SWF.hdr = (char*) header;
1218 spw_ioctl_send_SWF.hdr = (char*) header;
1206
1219
1207 // SET PACKET SEQUENCE CONTROL
1220 // SET PACKET SEQUENCE CONTROL
1208 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1221 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1209
1222
1210 // SET PACKET LENGTH AND BLKNR
1223 // SET PACKET LENGTH AND BLKNR
1211 if (i == 6)
1224 if (i == 6)
1212 {
1225 {
1213 spw_ioctl_send_SWF.dlen = BLK_NR_224 * NB_BYTES_SWF_BLK;
1226 spw_ioctl_send_SWF.dlen = BLK_NR_224 * NB_BYTES_SWF_BLK;
1214 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_224 >> 8);
1227 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_224 >> 8);
1215 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_224 );
1228 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_224 );
1216 header->blkNr[0] = (unsigned char) (BLK_NR_224 >> 8);
1229 header->blkNr[0] = (unsigned char) (BLK_NR_224 >> 8);
1217 header->blkNr[1] = (unsigned char) (BLK_NR_224 );
1230 header->blkNr[1] = (unsigned char) (BLK_NR_224 );
1218 }
1231 }
1219 else
1232 else
1220 {
1233 {
1221 spw_ioctl_send_SWF.dlen = BLK_NR_304 * NB_BYTES_SWF_BLK;
1234 spw_ioctl_send_SWF.dlen = BLK_NR_304 * NB_BYTES_SWF_BLK;
1222 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_304 >> 8);
1235 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_304 >> 8);
1223 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_304 );
1236 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_304 );
1224 header->blkNr[0] = (unsigned char) (BLK_NR_304 >> 8);
1237 header->blkNr[0] = (unsigned char) (BLK_NR_304 >> 8);
1225 header->blkNr[1] = (unsigned char) (BLK_NR_304 );
1238 header->blkNr[1] = (unsigned char) (BLK_NR_304 );
1226 }
1239 }
1227
1240
1228 // SET PACKET TIME
1241 // SET PACKET TIME
1229 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime );
1242 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime );
1230 //
1243 //
1231 header->time[0] = header->acquisitionTime[0];
1244 header->time[0] = header->acquisitionTime[0];
1232 header->time[1] = header->acquisitionTime[1];
1245 header->time[1] = header->acquisitionTime[1];
1233 header->time[2] = header->acquisitionTime[2];
1246 header->time[2] = header->acquisitionTime[2];
1234 header->time[3] = header->acquisitionTime[3];
1247 header->time[3] = header->acquisitionTime[3];
1235 header->time[4] = header->acquisitionTime[4];
1248 header->time[4] = header->acquisitionTime[4];
1236 header->time[5] = header->acquisitionTime[5];
1249 header->time[5] = header->acquisitionTime[5];
1237
1250
1238 // SET SID
1251 // SET SID
1239 header->sid = sid;
1252 header->sid = sid;
1240
1253
1241 // SET PKTNR
1254 // SET PKTNR
1242 header->pktNr = i+1; // PKT_NR
1255 header->pktNr = i+1; // PKT_NR
1243
1256
1244 // SEND PACKET
1257 // SEND PACKET
1245 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_SWF );
1258 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_SWF );
1246 if (status != RTEMS_SUCCESSFUL) {
1259 if (status != RTEMS_SUCCESSFUL) {
1247 ret = LFR_DEFAULT;
1260 ret = LFR_DEFAULT;
1248 }
1261 }
1249 }
1262 }
1250
1263
1251 return ret;
1264 return ret;
1252 }
1265 }
1253
1266
1254 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send,
1267 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send,
1255 Header_TM_LFR_SCIENCE_CWF_t *header )
1268 Header_TM_LFR_SCIENCE_CWF_t *header )
1256 {
1269 {
1257 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
1270 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
1258 *
1271 *
1259 * @param waveform points to the buffer containing the data that will be send.
1272 * @param waveform points to the buffer containing the data that will be send.
1260 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
1273 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
1261 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
1274 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
1262 * contain information to setup the transmission of the data packets.
1275 * contain information to setup the transmission of the data packets.
1263 *
1276 *
1264 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
1277 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
1265 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
1278 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
1266 *
1279 *
1267 */
1280 */
1268
1281
1269 unsigned int i;
1282 unsigned int i;
1270 int ret;
1283 int ret;
1271 unsigned int coarseTime;
1284 unsigned int coarseTime;
1272 unsigned int fineTime;
1285 unsigned int fineTime;
1273 rtems_status_code status;
1286 rtems_status_code status;
1274 spw_ioctl_pkt_send spw_ioctl_send_CWF;
1287 spw_ioctl_pkt_send spw_ioctl_send_CWF;
1275 char *dataPtr;
1288 char *dataPtr;
1276 unsigned char sid;
1289 unsigned char sid;
1277
1290
1278 spw_ioctl_send_CWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_CWF;
1291 spw_ioctl_send_CWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_CWF;
1279 spw_ioctl_send_CWF.options = 0;
1292 spw_ioctl_send_CWF.options = 0;
1280
1293
1281 ret = LFR_DEFAULT;
1294 ret = LFR_DEFAULT;
1282 sid = ring_node_to_send->sid;
1295 sid = ring_node_to_send->sid;
1283
1296
1284 coarseTime = ring_node_to_send->coarseTime;
1297 coarseTime = ring_node_to_send->coarseTime;
1285 fineTime = ring_node_to_send->fineTime;
1298 fineTime = ring_node_to_send->fineTime;
1286 dataPtr = (char*) ring_node_to_send->buffer_address;
1299 dataPtr = (char*) ring_node_to_send->buffer_address;
1287
1300
1288 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_672 >> 8);
1301 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_672 >> 8);
1289 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_672 );
1302 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_672 );
1290 header->hkBIA = pa_bia_status_info;
1303 header->hkBIA = pa_bia_status_info;
1291 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1304 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1292 header->blkNr[0] = (unsigned char) (BLK_NR_CWF_SHORT_F3 >> 8);
1305 header->blkNr[0] = (unsigned char) (BLK_NR_CWF_SHORT_F3 >> 8);
1293 header->blkNr[1] = (unsigned char) (BLK_NR_CWF_SHORT_F3 );
1306 header->blkNr[1] = (unsigned char) (BLK_NR_CWF_SHORT_F3 );
1294
1307
1295 //*********************
1308 //*********************
1296 // SEND CWF3_light DATA
1309 // SEND CWF3_light DATA
1297 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF_LIGHT; i++) // send waveform
1310 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF_LIGHT; i++) // send waveform
1298 {
1311 {
1299 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK) ];
1312 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK) ];
1300 spw_ioctl_send_CWF.hdr = (char*) header;
1313 spw_ioctl_send_CWF.hdr = (char*) header;
1301 // BUILD THE DATA
1314 // BUILD THE DATA
1302 spw_ioctl_send_CWF.dlen = BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK;
1315 spw_ioctl_send_CWF.dlen = BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK;
1303
1316
1304 // SET PACKET SEQUENCE COUNTER
1317 // SET PACKET SEQUENCE COUNTER
1305 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1318 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1306
1319
1307 // SET SID
1320 // SET SID
1308 header->sid = sid;
1321 header->sid = sid;
1309
1322
1310 // SET PACKET TIME
1323 // SET PACKET TIME
1311 compute_acquisition_time( coarseTime, fineTime, SID_NORM_CWF_F3, i, header->acquisitionTime );
1324 compute_acquisition_time( coarseTime, fineTime, SID_NORM_CWF_F3, i, header->acquisitionTime );
1312 //
1325 //
1313 header->time[0] = header->acquisitionTime[0];
1326 header->time[0] = header->acquisitionTime[0];
1314 header->time[1] = header->acquisitionTime[1];
1327 header->time[1] = header->acquisitionTime[1];
1315 header->time[2] = header->acquisitionTime[2];
1328 header->time[2] = header->acquisitionTime[2];
1316 header->time[3] = header->acquisitionTime[3];
1329 header->time[3] = header->acquisitionTime[3];
1317 header->time[4] = header->acquisitionTime[4];
1330 header->time[4] = header->acquisitionTime[4];
1318 header->time[5] = header->acquisitionTime[5];
1331 header->time[5] = header->acquisitionTime[5];
1319
1332
1320 // SET PACKET ID
1333 // SET PACKET ID
1321 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1334 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1322 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1335 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1323
1336
1324 // SEND PACKET
1337 // SEND PACKET
1325 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
1338 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
1326 if (status != RTEMS_SUCCESSFUL) {
1339 if (status != RTEMS_SUCCESSFUL) {
1327 ret = LFR_DEFAULT;
1340 ret = LFR_DEFAULT;
1328 }
1341 }
1329 }
1342 }
1330
1343
1331 return ret;
1344 return ret;
1332 }
1345 }
1333
1346
1334 void spw_send_asm_f0( ring_node *ring_node_to_send,
1347 void spw_send_asm_f0( ring_node *ring_node_to_send,
1335 Header_TM_LFR_SCIENCE_ASM_t *header )
1348 Header_TM_LFR_SCIENCE_ASM_t *header )
1336 {
1349 {
1337 unsigned int i;
1350 unsigned int i;
1338 unsigned int length = 0;
1351 unsigned int length = 0;
1339 rtems_status_code status;
1352 rtems_status_code status;
1340 unsigned int sid;
1353 unsigned int sid;
1341 float *spectral_matrix;
1354 float *spectral_matrix;
1342 int coarseTime;
1355 int coarseTime;
1343 int fineTime;
1356 int fineTime;
1344 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1357 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1345
1358
1346 sid = ring_node_to_send->sid;
1359 sid = ring_node_to_send->sid;
1347 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1360 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1348 coarseTime = ring_node_to_send->coarseTime;
1361 coarseTime = ring_node_to_send->coarseTime;
1349 fineTime = ring_node_to_send->fineTime;
1362 fineTime = ring_node_to_send->fineTime;
1350
1363
1351 header->biaStatusInfo = pa_bia_status_info;
1364 header->biaStatusInfo = pa_bia_status_info;
1352 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1365 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1353
1366
1354 for (i=0; i<3; i++)
1367 for (i=0; i<3; i++)
1355 {
1368 {
1356 if ((i==0) || (i==1))
1369 if ((i==0) || (i==1))
1357 {
1370 {
1358 spw_ioctl_send_ASM.dlen = DLEN_ASM_F0_PKT_1;
1371 spw_ioctl_send_ASM.dlen = DLEN_ASM_F0_PKT_1;
1359 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1372 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1360 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0_1) ) * NB_VALUES_PER_SM )
1373 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0_1) ) * NB_VALUES_PER_SM )
1361 ];
1374 ];
1362 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0_1;
1375 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0_1;
1363 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1376 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1364 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0_1) >> 8 ); // BLK_NR MSB
1377 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0_1) >> 8 ); // BLK_NR MSB
1365 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0_1); // BLK_NR LSB
1378 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0_1); // BLK_NR LSB
1366 }
1379 }
1367 else
1380 else
1368 {
1381 {
1369 spw_ioctl_send_ASM.dlen = DLEN_ASM_F0_PKT_2;
1382 spw_ioctl_send_ASM.dlen = DLEN_ASM_F0_PKT_2;
1370 spw_ioctl_send_ASM.data = (char*) &spectral_matrix[
1383 spw_ioctl_send_ASM.data = (char*) &spectral_matrix[
1371 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0_1) ) * NB_VALUES_PER_SM )
1384 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0_1) ) * NB_VALUES_PER_SM )
1372 ];
1385 ];
1373 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0_2;
1386 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0_2;
1374 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1387 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1375 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0_2) >> 8 ); // BLK_NR MSB
1388 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0_2) >> 8 ); // BLK_NR MSB
1376 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0_2); // BLK_NR LSB
1389 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0_2); // BLK_NR LSB
1377 }
1390 }
1378
1391
1379 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1392 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1380 spw_ioctl_send_ASM.hdr = (char *) header;
1393 spw_ioctl_send_ASM.hdr = (char *) header;
1381 spw_ioctl_send_ASM.options = 0;
1394 spw_ioctl_send_ASM.options = 0;
1382
1395
1383 // (2) BUILD THE HEADER
1396 // (2) BUILD THE HEADER
1384 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1397 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1385 header->packetLength[0] = (unsigned char) (length>>8);
1398 header->packetLength[0] = (unsigned char) (length>>8);
1386 header->packetLength[1] = (unsigned char) (length);
1399 header->packetLength[1] = (unsigned char) (length);
1387 header->sid = (unsigned char) sid; // SID
1400 header->sid = (unsigned char) sid; // SID
1388 header->pa_lfr_pkt_cnt_asm = 3;
1401 header->pa_lfr_pkt_cnt_asm = 3;
1389 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1402 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1390
1403
1391 // (3) SET PACKET TIME
1404 // (3) SET PACKET TIME
1392 header->time[0] = (unsigned char) (coarseTime>>24);
1405 header->time[0] = (unsigned char) (coarseTime>>24);
1393 header->time[1] = (unsigned char) (coarseTime>>16);
1406 header->time[1] = (unsigned char) (coarseTime>>16);
1394 header->time[2] = (unsigned char) (coarseTime>>8);
1407 header->time[2] = (unsigned char) (coarseTime>>8);
1395 header->time[3] = (unsigned char) (coarseTime);
1408 header->time[3] = (unsigned char) (coarseTime);
1396 header->time[4] = (unsigned char) (fineTime>>8);
1409 header->time[4] = (unsigned char) (fineTime>>8);
1397 header->time[5] = (unsigned char) (fineTime);
1410 header->time[5] = (unsigned char) (fineTime);
1398 //
1411 //
1399 header->acquisitionTime[0] = header->time[0];
1412 header->acquisitionTime[0] = header->time[0];
1400 header->acquisitionTime[1] = header->time[1];
1413 header->acquisitionTime[1] = header->time[1];
1401 header->acquisitionTime[2] = header->time[2];
1414 header->acquisitionTime[2] = header->time[2];
1402 header->acquisitionTime[3] = header->time[3];
1415 header->acquisitionTime[3] = header->time[3];
1403 header->acquisitionTime[4] = header->time[4];
1416 header->acquisitionTime[4] = header->time[4];
1404 header->acquisitionTime[5] = header->time[5];
1417 header->acquisitionTime[5] = header->time[5];
1405
1418
1406 // (4) SEND PACKET
1419 // (4) SEND PACKET
1407 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1420 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1408 if (status != RTEMS_SUCCESSFUL) {
1421 if (status != RTEMS_SUCCESSFUL) {
1409 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1422 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1410 }
1423 }
1411 }
1424 }
1412 }
1425 }
1413
1426
1414 void spw_send_asm_f1( ring_node *ring_node_to_send,
1427 void spw_send_asm_f1( ring_node *ring_node_to_send,
1415 Header_TM_LFR_SCIENCE_ASM_t *header )
1428 Header_TM_LFR_SCIENCE_ASM_t *header )
1416 {
1429 {
1417 unsigned int i;
1430 unsigned int i;
1418 unsigned int length = 0;
1431 unsigned int length = 0;
1419 rtems_status_code status;
1432 rtems_status_code status;
1420 unsigned int sid;
1433 unsigned int sid;
1421 float *spectral_matrix;
1434 float *spectral_matrix;
1422 int coarseTime;
1435 int coarseTime;
1423 int fineTime;
1436 int fineTime;
1424 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1437 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1425
1438
1426 sid = ring_node_to_send->sid;
1439 sid = ring_node_to_send->sid;
1427 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1440 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1428 coarseTime = ring_node_to_send->coarseTime;
1441 coarseTime = ring_node_to_send->coarseTime;
1429 fineTime = ring_node_to_send->fineTime;
1442 fineTime = ring_node_to_send->fineTime;
1430
1443
1431 header->biaStatusInfo = pa_bia_status_info;
1444 header->biaStatusInfo = pa_bia_status_info;
1432 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1445 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1433
1446
1434 for (i=0; i<3; i++)
1447 for (i=0; i<3; i++)
1435 {
1448 {
1436 if ((i==0) || (i==1))
1449 if ((i==0) || (i==1))
1437 {
1450 {
1438 spw_ioctl_send_ASM.dlen = DLEN_ASM_F1_PKT_1;
1451 spw_ioctl_send_ASM.dlen = DLEN_ASM_F1_PKT_1;
1439 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1452 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1440 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1_1) ) * NB_VALUES_PER_SM )
1453 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1_1) ) * NB_VALUES_PER_SM )
1441 ];
1454 ];
1442 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1_1;
1455 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1_1;
1443 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1456 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1444 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1_1) >> 8 ); // BLK_NR MSB
1457 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1_1) >> 8 ); // BLK_NR MSB
1445 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1_1); // BLK_NR LSB
1458 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1_1); // BLK_NR LSB
1446 }
1459 }
1447 else
1460 else
1448 {
1461 {
1449 spw_ioctl_send_ASM.dlen = DLEN_ASM_F1_PKT_2;
1462 spw_ioctl_send_ASM.dlen = DLEN_ASM_F1_PKT_2;
1450 spw_ioctl_send_ASM.data = (char*) &spectral_matrix[
1463 spw_ioctl_send_ASM.data = (char*) &spectral_matrix[
1451 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1_1) ) * NB_VALUES_PER_SM )
1464 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1_1) ) * NB_VALUES_PER_SM )
1452 ];
1465 ];
1453 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1_2;
1466 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1_2;
1454 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1467 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1455 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1_2) >> 8 ); // BLK_NR MSB
1468 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1_2) >> 8 ); // BLK_NR MSB
1456 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1_2); // BLK_NR LSB
1469 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1_2); // BLK_NR LSB
1457 }
1470 }
1458
1471
1459 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1472 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1460 spw_ioctl_send_ASM.hdr = (char *) header;
1473 spw_ioctl_send_ASM.hdr = (char *) header;
1461 spw_ioctl_send_ASM.options = 0;
1474 spw_ioctl_send_ASM.options = 0;
1462
1475
1463 // (2) BUILD THE HEADER
1476 // (2) BUILD THE HEADER
1464 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1477 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1465 header->packetLength[0] = (unsigned char) (length>>8);
1478 header->packetLength[0] = (unsigned char) (length>>8);
1466 header->packetLength[1] = (unsigned char) (length);
1479 header->packetLength[1] = (unsigned char) (length);
1467 header->sid = (unsigned char) sid; // SID
1480 header->sid = (unsigned char) sid; // SID
1468 header->pa_lfr_pkt_cnt_asm = 3;
1481 header->pa_lfr_pkt_cnt_asm = 3;
1469 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1482 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1470
1483
1471 // (3) SET PACKET TIME
1484 // (3) SET PACKET TIME
1472 header->time[0] = (unsigned char) (coarseTime>>24);
1485 header->time[0] = (unsigned char) (coarseTime>>24);
1473 header->time[1] = (unsigned char) (coarseTime>>16);
1486 header->time[1] = (unsigned char) (coarseTime>>16);
1474 header->time[2] = (unsigned char) (coarseTime>>8);
1487 header->time[2] = (unsigned char) (coarseTime>>8);
1475 header->time[3] = (unsigned char) (coarseTime);
1488 header->time[3] = (unsigned char) (coarseTime);
1476 header->time[4] = (unsigned char) (fineTime>>8);
1489 header->time[4] = (unsigned char) (fineTime>>8);
1477 header->time[5] = (unsigned char) (fineTime);
1490 header->time[5] = (unsigned char) (fineTime);
1478 //
1491 //
1479 header->acquisitionTime[0] = header->time[0];
1492 header->acquisitionTime[0] = header->time[0];
1480 header->acquisitionTime[1] = header->time[1];
1493 header->acquisitionTime[1] = header->time[1];
1481 header->acquisitionTime[2] = header->time[2];
1494 header->acquisitionTime[2] = header->time[2];
1482 header->acquisitionTime[3] = header->time[3];
1495 header->acquisitionTime[3] = header->time[3];
1483 header->acquisitionTime[4] = header->time[4];
1496 header->acquisitionTime[4] = header->time[4];
1484 header->acquisitionTime[5] = header->time[5];
1497 header->acquisitionTime[5] = header->time[5];
1485
1498
1486 // (4) SEND PACKET
1499 // (4) SEND PACKET
1487 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1500 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1488 if (status != RTEMS_SUCCESSFUL) {
1501 if (status != RTEMS_SUCCESSFUL) {
1489 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1502 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1490 }
1503 }
1491 }
1504 }
1492 }
1505 }
1493
1506
1494 void spw_send_asm_f2( ring_node *ring_node_to_send,
1507 void spw_send_asm_f2( ring_node *ring_node_to_send,
1495 Header_TM_LFR_SCIENCE_ASM_t *header )
1508 Header_TM_LFR_SCIENCE_ASM_t *header )
1496 {
1509 {
1497 unsigned int i;
1510 unsigned int i;
1498 unsigned int length = 0;
1511 unsigned int length = 0;
1499 rtems_status_code status;
1512 rtems_status_code status;
1500 unsigned int sid;
1513 unsigned int sid;
1501 float *spectral_matrix;
1514 float *spectral_matrix;
1502 int coarseTime;
1515 int coarseTime;
1503 int fineTime;
1516 int fineTime;
1504 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1517 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1505
1518
1506 sid = ring_node_to_send->sid;
1519 sid = ring_node_to_send->sid;
1507 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1520 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1508 coarseTime = ring_node_to_send->coarseTime;
1521 coarseTime = ring_node_to_send->coarseTime;
1509 fineTime = ring_node_to_send->fineTime;
1522 fineTime = ring_node_to_send->fineTime;
1510
1523
1511 header->biaStatusInfo = pa_bia_status_info;
1524 header->biaStatusInfo = pa_bia_status_info;
1512 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1525 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1513
1526
1514 for (i=0; i<3; i++)
1527 for (i=0; i<3; i++)
1515 {
1528 {
1516
1529
1517 spw_ioctl_send_ASM.dlen = DLEN_ASM_F2_PKT;
1530 spw_ioctl_send_ASM.dlen = DLEN_ASM_F2_PKT;
1518 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1531 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1519 ( (ASM_F2_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F2) ) * NB_VALUES_PER_SM )
1532 ( (ASM_F2_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F2) ) * NB_VALUES_PER_SM )
1520 ];
1533 ];
1521 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F2;
1534 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F2;
1522 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3;
1535 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3;
1523 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F2) >> 8 ); // BLK_NR MSB
1536 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F2) >> 8 ); // BLK_NR MSB
1524 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F2); // BLK_NR LSB
1537 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F2); // BLK_NR LSB
1525
1538
1526 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1539 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1527 spw_ioctl_send_ASM.hdr = (char *) header;
1540 spw_ioctl_send_ASM.hdr = (char *) header;
1528 spw_ioctl_send_ASM.options = 0;
1541 spw_ioctl_send_ASM.options = 0;
1529
1542
1530 // (2) BUILD THE HEADER
1543 // (2) BUILD THE HEADER
1531 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1544 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1532 header->packetLength[0] = (unsigned char) (length>>8);
1545 header->packetLength[0] = (unsigned char) (length>>8);
1533 header->packetLength[1] = (unsigned char) (length);
1546 header->packetLength[1] = (unsigned char) (length);
1534 header->sid = (unsigned char) sid; // SID
1547 header->sid = (unsigned char) sid; // SID
1535 header->pa_lfr_pkt_cnt_asm = 3;
1548 header->pa_lfr_pkt_cnt_asm = 3;
1536 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1549 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1537
1550
1538 // (3) SET PACKET TIME
1551 // (3) SET PACKET TIME
1539 header->time[0] = (unsigned char) (coarseTime>>24);
1552 header->time[0] = (unsigned char) (coarseTime>>24);
1540 header->time[1] = (unsigned char) (coarseTime>>16);
1553 header->time[1] = (unsigned char) (coarseTime>>16);
1541 header->time[2] = (unsigned char) (coarseTime>>8);
1554 header->time[2] = (unsigned char) (coarseTime>>8);
1542 header->time[3] = (unsigned char) (coarseTime);
1555 header->time[3] = (unsigned char) (coarseTime);
1543 header->time[4] = (unsigned char) (fineTime>>8);
1556 header->time[4] = (unsigned char) (fineTime>>8);
1544 header->time[5] = (unsigned char) (fineTime);
1557 header->time[5] = (unsigned char) (fineTime);
1545 //
1558 //
1546 header->acquisitionTime[0] = header->time[0];
1559 header->acquisitionTime[0] = header->time[0];
1547 header->acquisitionTime[1] = header->time[1];
1560 header->acquisitionTime[1] = header->time[1];
1548 header->acquisitionTime[2] = header->time[2];
1561 header->acquisitionTime[2] = header->time[2];
1549 header->acquisitionTime[3] = header->time[3];
1562 header->acquisitionTime[3] = header->time[3];
1550 header->acquisitionTime[4] = header->time[4];
1563 header->acquisitionTime[4] = header->time[4];
1551 header->acquisitionTime[5] = header->time[5];
1564 header->acquisitionTime[5] = header->time[5];
1552
1565
1553 // (4) SEND PACKET
1566 // (4) SEND PACKET
1554 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1567 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1555 if (status != RTEMS_SUCCESSFUL) {
1568 if (status != RTEMS_SUCCESSFUL) {
1556 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1569 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1557 }
1570 }
1558 }
1571 }
1559 }
1572 }
1560
1573
1561 void spw_send_k_dump( ring_node *ring_node_to_send )
1574 void spw_send_k_dump( ring_node *ring_node_to_send )
1562 {
1575 {
1563 rtems_status_code status;
1576 rtems_status_code status;
1564 Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *kcoefficients_dump;
1577 Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *kcoefficients_dump;
1565 unsigned int packetLength;
1578 unsigned int packetLength;
1566 unsigned int size;
1579 unsigned int size;
1567
1580
1568 PRINTF("spw_send_k_dump\n")
1581 PRINTF("spw_send_k_dump\n")
1569
1582
1570 kcoefficients_dump = (Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *) ring_node_to_send->buffer_address;
1583 kcoefficients_dump = (Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *) ring_node_to_send->buffer_address;
1571
1584
1572 packetLength = kcoefficients_dump->packetLength[0] * 256 + kcoefficients_dump->packetLength[1];
1585 packetLength = kcoefficients_dump->packetLength[0] * 256 + kcoefficients_dump->packetLength[1];
1573
1586
1574 size = packetLength + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
1587 size = packetLength + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
1575
1588
1576 PRINTF2("packetLength %d, size %d\n", packetLength, size )
1589 PRINTF2("packetLength %d, size %d\n", packetLength, size )
1577
1590
1578 status = write( fdSPW, (char *) ring_node_to_send->buffer_address, size );
1591 status = write( fdSPW, (char *) ring_node_to_send->buffer_address, size );
1579
1592
1580 if (status == -1){
1593 if (status == -1){
1581 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
1594 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
1582 }
1595 }
1583
1596
1584 ring_node_to_send->status = 0x00;
1597 ring_node_to_send->status = 0x00;
1585 }
1598 }
General Comments 0
You need to be logged in to leave comments. Login now