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