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