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