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