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