##// END OF EJS Templates
Disabled most dead code + set CMake min Ver to 3.5
jeandet -
r402:eb452cd0caf8 R3++ draft
parent child
Show More
@@ -1,14 +1,14
1 cmake_minimum_required (VERSION 3.6)
1 cmake_minimum_required (VERSION 3.5)
2 project (LFR_FSW)
2 project (LFR_FSW)
3
3
4 if(NOT CMAKE_BUILD_TYPE)
4 if(NOT CMAKE_BUILD_TYPE)
5 set(CMAKE_BUILD_TYPE "Release" CACHE STRING
5 set(CMAKE_BUILD_TYPE "Release" CACHE STRING
6 "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
6 "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
7 endif(NOT CMAKE_BUILD_TYPE)
7 endif(NOT CMAKE_BUILD_TYPE)
8
8
9 set(LFR_BP_SRC ${CMAKE_CURRENT_SOURCE_DIR}/LFR_basic-parameters/basic_parameters.c)
9 set(LFR_BP_SRC ${CMAKE_CURRENT_SOURCE_DIR}/LFR_basic-parameters/basic_parameters.c)
10
10
11 SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/sparc")
11 SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/sparc")
12
12
13 add_subdirectory(libgcov)
13 add_subdirectory(libgcov)
14 add_subdirectory(src)
14 add_subdirectory(src)
@@ -1,117 +1,112
1 #ifndef TC_HANDLER_H_INCLUDED
1 #ifndef TC_HANDLER_H_INCLUDED
2 #define TC_HANDLER_H_INCLUDED
2 #define TC_HANDLER_H_INCLUDED
3
3
4 #include <rtems.h>
4 #include <rtems.h>
5 #include <leon.h>
5 #include <leon.h>
6
6
7 #include "tc_load_dump_parameters.h"
7 #include "tc_load_dump_parameters.h"
8 #include "tc_acceptance.h"
8 #include "tc_acceptance.h"
9 #include "tm_lfr_tc_exe.h"
9 #include "tm_lfr_tc_exe.h"
10 #include "wf_handler.h"
10 #include "wf_handler.h"
11 #include "fsw_processing.h"
11 #include "fsw_processing.h"
12
12
13 #include "lfr_cpu_usage_report.h"
13 #include "lfr_cpu_usage_report.h"
14
14
15 #define MAX_DELTA_COARSE_TIME 3
15 #define MAX_DELTA_COARSE_TIME 3
16 #define NB_SCIENCE_TASKS 10
16 #define NB_SCIENCE_TASKS 10
17 #define NB_ASM_TASKS 6
17 #define NB_ASM_TASKS 6
18 #define STATUS_0 0
18 #define STATUS_0 0
19 #define STATUS_1 1
19 #define STATUS_1 1
20 #define STATUS_2 2
20 #define STATUS_2 2
21 #define STATUS_3 3
21 #define STATUS_3 3
22 #define STATUS_4 4
22 #define STATUS_4 4
23 #define STATUS_5 5
23 #define STATUS_5 5
24 #define STATUS_6 6
24 #define STATUS_6 6
25 #define STATUS_7 7
25 #define STATUS_7 7
26 #define STATUS_8 8
26 #define STATUS_8 8
27 #define STATUS_9 9
27 #define STATUS_9 9
28
28
29 #define CAL_F0 625.
29 #define CAL_F0 625.
30 #define CAL_F1 10000.
30 #define CAL_F1 10000.
31 #define CAL_W0 (2. * pi * CAL_F0)
31 #define CAL_W0 (2. * pi * CAL_F0)
32 #define CAL_W1 (2. * pi * CAL_F1)
32 #define CAL_W1 (2. * pi * CAL_F1)
33 #define CAL_A0 1.
33 #define CAL_A0 1.
34 #define CAL_A1 2.
34 #define CAL_A1 2.
35 #define CAL_FS 160256.410
35 #define CAL_FS 160256.410
36 #define CAL_SCALE_FACTOR (0.250 / 0.000654) // 191, 500 mVpp, 2 sinus waves => 500 mVpp each, amplitude = 250 mV
36 #define CAL_SCALE_FACTOR (0.250 / 0.000654) // 191, 500 mVpp, 2 sinus waves => 500 mVpp each, amplitude = 250 mV
37 #define CAL_NB_PTS 256
37 #define CAL_NB_PTS 256
38 #define CAL_DATA_MASK 0xfff
38 #define CAL_DATA_MASK 0xfff
39 #define CAL_F_DIVISOR 38 // 25 MHz => 160 256 (39 - 1)
39 #define CAL_F_DIVISOR 38 // 25 MHz => 160 256 (39 - 1)
40 #define CAL_F_DIVISOR_MIN 38
40 #define CAL_F_DIVISOR_MIN 38
41 #define CAL_F_DIVISOR_MAX (38*2*2*2*2)
41 #define CAL_F_DIVISOR_MAX (38*2*2*2*2)
42 // INTERLEAVED MODE
42 // INTERLEAVED MODE
43 #define CAL_FS_INTER 240384.615
43 #define CAL_FS_INTER 240384.615
44 #define CAL_NB_PTS_INTER 384
44 #define CAL_NB_PTS_INTER 384
45 #define CAL_DATA_MASK_INTER 0x3f
45 #define CAL_DATA_MASK_INTER 0x3f
46 #define CAL_DATA_SHIFT_INTER 12
46 #define CAL_DATA_SHIFT_INTER 12
47 #define BYTES_FOR_2_SAMPLES 3 // one need 3 bytes = 24 bits to store 3 samples of 12 bits in interleaved mode
47 #define BYTES_FOR_2_SAMPLES 3 // one need 3 bytes = 24 bits to store 3 samples of 12 bits in interleaved mode
48 #define STEPS_FOR_STORAGE_INTER 128
48 #define STEPS_FOR_STORAGE_INTER 128
49 #define CAL_F_DIVISOR_INTER 26 // 25 MHz => 240 384
49 #define CAL_F_DIVISOR_INTER 26 // 25 MHz => 240 384
50
50
51 extern unsigned int lastValidEnterModeTime;
51 extern unsigned int lastValidEnterModeTime;
52 extern unsigned char oneTcLfrUpdateTimeReceived;
52 extern unsigned char oneTcLfrUpdateTimeReceived;
53
53
54 //****
55 // ISR
56 rtems_isr commutation_isr1( rtems_vector_number vector );
57 rtems_isr commutation_isr2( rtems_vector_number vector );
58
59 //***********
54 //***********
60 // RTEMS TASK
55 // RTEMS TASK
61 rtems_task actn_task( rtems_task_argument unused );
56 rtems_task actn_task( rtems_task_argument unused );
62
57
63 //***********
58 //***********
64 // TC ACTIONS
59 // TC ACTIONS
65 int action_reset( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
60 int action_reset( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
66 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id);
61 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id);
67 int action_update_info( ccsdsTelecommandPacket_t *TC, rtems_id queue_id );
62 int action_update_info( ccsdsTelecommandPacket_t *TC, rtems_id queue_id );
68 int action_enable_calibration( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
63 int action_enable_calibration( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
69 int action_disable_calibration( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
64 int action_disable_calibration( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
70 int action_update_time( ccsdsTelecommandPacket_t *TC);
65 int action_update_time( ccsdsTelecommandPacket_t *TC);
71
66
72 // mode transition
67 // mode transition
73 int check_mode_value( unsigned char requestedMode );
68 int check_mode_value( unsigned char requestedMode );
74 int check_mode_transition( unsigned char requestedMode );
69 int check_mode_transition( unsigned char requestedMode );
75 void update_last_valid_transition_date( unsigned int transitionCoarseTime );
70 void update_last_valid_transition_date( unsigned int transitionCoarseTime );
76 int check_transition_date( unsigned int transitionCoarseTime );
71 int check_transition_date( unsigned int transitionCoarseTime );
77 int stop_spectral_matrices( void );
72 int stop_spectral_matrices( void );
78 int stop_current_mode( void );
73 int stop_current_mode( void );
79 int enter_mode_standby(void );
74 int enter_mode_standby(void );
80 int enter_mode_normal( unsigned int transitionCoarseTime );
75 int enter_mode_normal( unsigned int transitionCoarseTime );
81 int enter_mode_burst( unsigned int transitionCoarseTime );
76 int enter_mode_burst( unsigned int transitionCoarseTime );
82 int enter_mode_sbm1( unsigned int transitionCoarseTime );
77 int enter_mode_sbm1( unsigned int transitionCoarseTime );
83 int enter_mode_sbm2( unsigned int transitionCoarseTime );
78 int enter_mode_sbm2( unsigned int transitionCoarseTime );
84 int restart_science_tasks( unsigned char lfrRequestedMode );
79 int restart_science_tasks( unsigned char lfrRequestedMode );
85 int restart_asm_tasks(unsigned char lfrRequestedMode );
80 int restart_asm_tasks(unsigned char lfrRequestedMode );
86 int suspend_science_tasks(void);
81 int suspend_science_tasks(void);
87 int suspend_asm_tasks( void );
82 int suspend_asm_tasks( void );
88 void launch_waveform_picker( unsigned char mode , unsigned int transitionCoarseTime );
83 void launch_waveform_picker( unsigned char mode , unsigned int transitionCoarseTime );
89 void launch_spectral_matrix( void );
84 void launch_spectral_matrix( void );
90 void set_sm_irq_onNewMatrix( unsigned char value );
85 void set_sm_irq_onNewMatrix( unsigned char value );
91 void set_sm_irq_onError( unsigned char value );
86 void set_sm_irq_onError( unsigned char value );
92
87
93 // other functions
88 // other functions
94 void updateLFRCurrentMode(unsigned char requestedMode);
89 void updateLFRCurrentMode(unsigned char requestedMode);
95 void set_lfr_soft_reset( unsigned char value );
90 void set_lfr_soft_reset( unsigned char value );
96 void reset_lfr( void );
91 void reset_lfr( void );
97 // CALIBRATION
92 // CALIBRATION
98 void setCalibrationPrescaler( unsigned int prescaler );
93 void setCalibrationPrescaler( unsigned int prescaler );
99 void setCalibrationDivisor( unsigned int divisionFactor );
94 void setCalibrationDivisor( unsigned int divisionFactor );
100 void setCalibrationData( void );
95 void setCalibrationData( void );
101 void setCalibrationReload( bool state);
96 void setCalibrationReload( bool state);
102 void setCalibrationEnable( bool state );
97 void setCalibrationEnable( bool state );
103 void setCalibrationInterleaved( bool state );
98 void setCalibrationInterleaved( bool state );
104 void setCalibration( bool state );
99 void setCalibration( bool state );
105 void configureCalibration( bool interleaved );
100 void configureCalibration( bool interleaved );
106 //
101 //
107 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC , unsigned char *time );
102 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC , unsigned char *time );
108 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC , unsigned char *time );
103 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC , unsigned char *time );
109 void close_action( ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id );
104 void close_action( ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id );
110
105
111 extern rtems_status_code get_message_queue_id_send( rtems_id *queue_id );
106 extern rtems_status_code get_message_queue_id_send( rtems_id *queue_id );
112 extern rtems_status_code get_message_queue_id_recv( rtems_id *queue_id );
107 extern rtems_status_code get_message_queue_id_recv( rtems_id *queue_id );
113
108
114 #endif // TC_HANDLER_H_INCLUDED
109 #endif // TC_HANDLER_H_INCLUDED
115
110
116
111
117
112
@@ -1,20 +1,20
1 cmake_minimum_required(VERSION 3.6)
1 cmake_minimum_required(VERSION 3.5)
2 project(libgcov C)
2 project(libgcov C)
3 include(sparc-rtems)
3 include(sparc-rtems)
4 include(cppcheck)
4 include(cppcheck)
5
5
6 set(LIB_GCOV_SOURCES
6 set(LIB_GCOV_SOURCES
7 gcov-io.c
7 gcov-io.c
8 gcov-io.h
8 gcov-io.h
9 gcov-iov.h
9 gcov-iov.h
10 libgcov.c
10 libgcov.c
11 )
11 )
12 if(Coverage)
12 if(Coverage)
13 # add_definitions(-DGCOV_USE_EXIT)
13 add_definitions(-DGCOV_USE_EXIT)
14 add_definitions(-DGCOV_ENABLED)
14 add_definitions(-DGCOV_ENABLED)
15 endif()
15 endif()
16 add_library(gcov STATIC ${LIB_GCOV_SOURCES})
16 add_library(gcov STATIC ${LIB_GCOV_SOURCES})
17
17
18 add_custom_target(gcovr
18 add_custom_target(gcovr
19 COMMAND gcovr --exclude='.*gcov.*' --gcov-executable=${rtems_dir}/bin/sparc-rtems-gcov --object-directory ${CMAKE_BINARY_DIR} -r ${CMAKE_SOURCE_DIR} --html --html-details -o ${CMAKE_CURRENT_BINARY_DIR}/gcov.html && xdg-open ${CMAKE_CURRENT_BINARY_DIR}/gcov.html
19 COMMAND gcovr --exclude='.*gcov.*' --gcov-executable=${rtems_dir}/bin/sparc-rtems-gcov --object-directory ${CMAKE_BINARY_DIR} -r ${CMAKE_SOURCE_DIR} --html --html-details -o ${CMAKE_CURRENT_BINARY_DIR}/gcov.html && xdg-open ${CMAKE_CURRENT_BINARY_DIR}/gcov.html
20 )
20 )
@@ -1,39 +1,39
1 set(rtems_dir /opt/rtems-4.10/)
1 set(rtems_dir /opt/rtems-4.10/)
2
2
3 set(CMAKE_SYSTEM_NAME rtems)
3 set(CMAKE_SYSTEM_NAME rtems)
4 set(CMAKE_C_COMPILER ${rtems_dir}/bin/sparc-rtems-gcc)
4 set(CMAKE_C_COMPILER ${rtems_dir}/bin/sparc-rtems-gcc)
5 set(CMAKE_CXX_COMPILER ${rtems_dir}/bin/sparc-rtems-g++)
5 set(CMAKE_CXX_COMPILER ${rtems_dir}/bin/sparc-rtems-g++)
6 set(CMAKE_LINKER ${rtems_dir}/bin/sparc-rtems-g++)
6 set(CMAKE_LINKER ${rtems_dir}/bin/sparc-rtems-g++)
7 SET(CMAKE_EXE_LINKER_FLAGS "-static")
7 SET(CMAKE_EXE_LINKER_FLAGS "-static")
8 option(fix-b2bst "Activate -mfix-b2bst switch to mitigate \"LEON3FT Stale Cache Entry After Store with Data Tag Parity Error\" errata, GRLIB-TN-0009" ON)
8 option(fix-b2bst "Activate -mfix-b2bst switch to mitigate \"LEON3FT Stale Cache Entry After Store with Data Tag Parity Error\" errata, GRLIB-TN-0009" ON)
9
9
10 option(Coverage "Enables code coverage" OFF)
10 option(Coverage "Enables code coverage" OFF)
11
11
12
12
13 set(CMAKE_C_FLAGS_RELEASE "-O2")
13 set(CMAKE_C_FLAGS_RELEASE "-O2")
14 set(CMAKE_C_FLAGS_DEBUG "-O2 -g -fno-inline")
14 set(CMAKE_C_FLAGS_DEBUG "-O2 -g3 -fno-inline")
15
15
16
16
17 if(fix-b2bst)
17 if(fix-b2bst)
18 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mfix-b2bst")
18 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mfix-b2bst")
19 set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -mfix-b2bst")
19 set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -mfix-b2bst")
20 endif()
20 endif()
21
21
22
22
23 set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_LINKER> <FLAGS> -Xlinker -Map=<TARGET>.map <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
23 set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_LINKER> <FLAGS> -Xlinker -Map=<TARGET>.map <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
24
24
25 include_directories("${rtems_dir}/sparc-rtems/leon3/lib/include")
25 include_directories("${rtems_dir}/sparc-rtems/leon3/lib/include")
26
26
27 function (check_b2bst target bin)
27 function (check_b2bst target bin)
28 add_custom_command(TARGET ${target}
28 add_custom_command(TARGET ${target}
29 POST_BUILD
29 POST_BUILD
30 COMMAND ${rtems_dir}/bin/sparc-rtems-objdump -d ${bin}/${target} | ${CMAKE_SOURCE_DIR}/sparc/leon3ft-b2bst-scan.tcl
30 COMMAND ${rtems_dir}/bin/sparc-rtems-objdump -d ${bin}/${target} | ${CMAKE_SOURCE_DIR}/sparc/leon3ft-b2bst-scan.tcl
31 )
31 )
32 endfunction()
32 endfunction()
33
33
34 function (build_srec target bin rev)
34 function (build_srec target bin rev)
35 add_custom_command(TARGET ${target}
35 add_custom_command(TARGET ${target}
36 POST_BUILD
36 POST_BUILD
37 COMMAND ${rtems_dir}/bin/sparc-rtems-objcopy -j .data -F srec ${bin}/${target} RpwLfrApp_XXXX_data_rev-${rev}.srec && ${rtems_dir}/bin/sparc-rtems-objcopy -j .text -F srec ${bin}/${target} RpwLfrApp_XXXX_text_rev-${rev}.srec
37 COMMAND ${rtems_dir}/bin/sparc-rtems-objcopy -j .data -F srec ${bin}/${target} RpwLfrApp_XXXX_data_rev-${rev}.srec && ${rtems_dir}/bin/sparc-rtems-objcopy -j .text -F srec ${bin}/${target} RpwLfrApp_XXXX_text_rev-${rev}.srec
38 )
38 )
39 endfunction()
39 endfunction()
@@ -1,130 +1,136
1 cmake_minimum_required (VERSION 3.6)
1 cmake_minimum_required (VERSION 3.5)
2 project (fsw)
2 project (fsw)
3
3
4 include(sparc-rtems)
4 include(sparc-rtems)
5 include(cppcheck)
5 include(cppcheck)
6
6
7 include_directories("../header"
7 include_directories("../header"
8 "../header/lfr_common_headers"
8 "../header/lfr_common_headers"
9 "../header/processing"
9 "../header/processing"
10 "../LFR_basic-parameters"
10 "../LFR_basic-parameters"
11 "../src")
11 "../src")
12
12
13 set(SOURCES wf_handler.c
13 set(SOURCES wf_handler.c
14 tc_handler.c
14 tc_handler.c
15 fsw_misc.c
15 fsw_misc.c
16 fsw_init.c
16 fsw_init.c
17 fsw_globals.c
17 fsw_globals.c
18 fsw_spacewire.c
18 fsw_spacewire.c
19 tc_load_dump_parameters.c
19 tc_load_dump_parameters.c
20 tm_lfr_tc_exe.c
20 tm_lfr_tc_exe.c
21 tc_acceptance.c
21 tc_acceptance.c
22 processing/fsw_processing.c
22 processing/fsw_processing.c
23 processing/avf0_prc0.c
23 processing/avf0_prc0.c
24 processing/avf1_prc1.c
24 processing/avf1_prc1.c
25 processing/avf2_prc2.c
25 processing/avf2_prc2.c
26 lfr_cpu_usage_report.c
26 lfr_cpu_usage_report.c
27 ${LFR_BP_SRC}
27 ${LFR_BP_SRC}
28 ../header/wf_handler.h
28 ../header/wf_handler.h
29 ../header/tc_handler.h
29 ../header/tc_handler.h
30 ../header/grlib_regs.h
30 ../header/grlib_regs.h
31 ../header/fsw_misc.h
31 ../header/fsw_misc.h
32 ../header/fsw_init.h
32 ../header/fsw_init.h
33 ../header/fsw_spacewire.h
33 ../header/fsw_spacewire.h
34 ../header/tc_load_dump_parameters.h
34 ../header/tc_load_dump_parameters.h
35 ../header/tm_lfr_tc_exe.h
35 ../header/tm_lfr_tc_exe.h
36 ../header/tc_acceptance.h
36 ../header/tc_acceptance.h
37 ../header/processing/fsw_processing.h
37 ../header/processing/fsw_processing.h
38 ../header/processing/avf0_prc0.h
38 ../header/processing/avf0_prc0.h
39 ../header/processing/avf1_prc1.h
39 ../header/processing/avf1_prc1.h
40 ../header/processing/avf2_prc2.h
40 ../header/processing/avf2_prc2.h
41 ../header/fsw_params_wf_handler.h
41 ../header/fsw_params_wf_handler.h
42 ../header/lfr_cpu_usage_report.h
42 ../header/lfr_cpu_usage_report.h
43 ../header/lfr_common_headers/ccsds_types.h
43 ../header/lfr_common_headers/ccsds_types.h
44 ../header/lfr_common_headers/fsw_params.h
44 ../header/lfr_common_headers/fsw_params.h
45 ../header/lfr_common_headers/fsw_params_nb_bytes.h
45 ../header/lfr_common_headers/fsw_params_nb_bytes.h
46 ../header/lfr_common_headers/fsw_params_processing.h
46 ../header/lfr_common_headers/fsw_params_processing.h
47 ../header/lfr_common_headers/tm_byte_positions.h
47 ../header/lfr_common_headers/tm_byte_positions.h
48 ../LFR_basic-parameters/basic_parameters.h
48 ../LFR_basic-parameters/basic_parameters.h
49 ../LFR_basic-parameters/basic_parameters_params.h
49 ../LFR_basic-parameters/basic_parameters_params.h
50 ../header/GscMemoryLPP.hpp
50 ../header/GscMemoryLPP.hpp
51 )
51 )
52
52
53
53
54 option(FSW_verbose "Enable verbose LFR" OFF)
54 option(FSW_verbose "Enable verbose LFR" OFF)
55 option(FSW_boot_messages "Enable LFR boot messages" OFF)
55 option(FSW_boot_messages "Enable LFR boot messages" OFF)
56 option(FSW_debug_messages "Enable LFR debug messages" OFF)
56 option(FSW_debug_messages "Enable LFR debug messages" OFF)
57 option(FSW_cpu_usage_report "Enable LFR cpu usage report" OFF)
57 option(FSW_cpu_usage_report "Enable LFR cpu usage report" OFF)
58 option(FSW_stack_report "Enable LFR stack report" OFF)
58 option(FSW_stack_report "Enable LFR stack report" OFF)
59 option(FSW_vhdl_dev "?" OFF)
59 option(FSW_vhdl_dev "?" OFF)
60 option(FSW_lpp_dpu_destid "Set to debug at LPP" OFF)
60 option(FSW_lpp_dpu_destid "Set to debug at LPP" OFF)
61 option(FSW_debug_watchdog "Enable debug watchdog" OFF)
61 option(FSW_debug_watchdog "Enable debug watchdog" OFF)
62 option(FSW_debug_tch "?" OFF)
62 option(FSW_debug_tch "?" OFF)
63 option(FSW_Instrument_Scrubbing "Enable scrubbing counter" OFF)
63 option(FSW_Instrument_Scrubbing "Enable scrubbing counter" OFF)
64 option(FSW_Enable_Dead_Code "Enable dead code compilation, this is used to hide by default unused code." OFF)
64
65
65 set(SW_VERSION_N1 "3" CACHE STRING "Choose N1 FSW Version." FORCE)
66 set(SW_VERSION_N1 "3" CACHE STRING "Choose N1 FSW Version." FORCE)
66 set(SW_VERSION_N2 "2" CACHE STRING "Choose N2 FSW Version." FORCE)
67 set(SW_VERSION_N2 "2" CACHE STRING "Choose N2 FSW Version." FORCE)
67 set(SW_VERSION_N3 "0" CACHE STRING "Choose N3 FSW Version." FORCE)
68 set(SW_VERSION_N3 "0" CACHE STRING "Choose N3 FSW Version." FORCE)
68 set(SW_VERSION_N4 "22" CACHE STRING "Choose N4 FSW Version." FORCE)
69 set(SW_VERSION_N4 "22" CACHE STRING "Choose N4 FSW Version." FORCE)
69
70
70 if(FSW_verbose)
71 if(FSW_verbose)
71 add_definitions(-DPRINT_MESSAGES_ON_CONSOLE)
72 add_definitions(-DPRINT_MESSAGES_ON_CONSOLE)
72 endif()
73 endif()
73 if(FSW_boot_messages)
74 if(FSW_boot_messages)
74 add_definitions(-DBOOT_MESSAGES)
75 add_definitions(-DBOOT_MESSAGES)
75 endif()
76 endif()
76 if(FSW_debug_messages)
77 if(FSW_debug_messages)
77 add_definitions(-DDEBUG_MESSAGES)
78 add_definitions(-DDEBUG_MESSAGES)
78 endif()
79 endif()
79 if(FSW_cpu_usage_report)
80 if(FSW_cpu_usage_report)
80 add_definitions(-DPRINT_TASK_STATISTICS)
81 add_definitions(-DPRINT_TASK_STATISTICS)
81 endif()
82 endif()
82 if(FSW_stack_report)
83 if(FSW_stack_report)
83 add_definitions(-DPRINT_STACK_REPORT)
84 add_definitions(-DPRINT_STACK_REPORT)
84 endif()
85 endif()
85 if(FSW_vhdl_dev)
86 if(FSW_vhdl_dev)
86 add_definitions(-DVHDL_DEV)
87 add_definitions(-DVHDL_DEV)
87 endif()
88 endif()
88 if(FSW_lpp_dpu_destid)
89 if(FSW_lpp_dpu_destid)
89 add_definitions(-DLPP_DPU_DESTID)
90 add_definitions(-DLPP_DPU_DESTID)
90 endif()
91 endif()
91 if(FSW_debug_watchdog)
92 if(FSW_debug_watchdog)
92 add_definitions(-DDEBUG_WATCHDOG)
93 add_definitions(-DDEBUG_WATCHDOG)
93 endif()
94 endif()
94 if(FSW_debug_tch)
95 if(FSW_debug_tch)
95 add_definitions(-DDEBUG_TCH)
96 add_definitions(-DDEBUG_TCH)
96 endif()
97 endif()
97
98
99 if(FSW_Enable_Dead_Code)
100 add_definitions(-DENABLE_DEAD_CODE)
101 endif()
102
103
98
104
99
105
100 add_definitions(-DMSB_FIRST_TCH)
106 add_definitions(-DMSB_FIRST_TCH)
101
107
102 add_definitions(-DSWVERSION=-1-0)
108 add_definitions(-DSWVERSION=-1-0)
103 add_definitions(-DSW_VERSION_N1=${SW_VERSION_N1})
109 add_definitions(-DSW_VERSION_N1=${SW_VERSION_N1})
104 add_definitions(-DSW_VERSION_N2=${SW_VERSION_N2})
110 add_definitions(-DSW_VERSION_N2=${SW_VERSION_N2})
105 add_definitions(-DSW_VERSION_N3=${SW_VERSION_N3})
111 add_definitions(-DSW_VERSION_N3=${SW_VERSION_N3})
106 add_definitions(-DSW_VERSION_N4=${SW_VERSION_N4})
112 add_definitions(-DSW_VERSION_N4=${SW_VERSION_N4})
107
113
108 add_executable(fsw ${SOURCES})
114 add_executable(fsw ${SOURCES})
109
115
110 if(FSW_Instrument_Scrubbing)
116 if(FSW_Instrument_Scrubbing)
111 add_definitions(-DENABLE_SCRUBBING_COUNTER)
117 add_definitions(-DENABLE_SCRUBBING_COUNTER)
112 endif()
118 endif()
113
119
114 if(Coverage)
120 if(Coverage)
115 target_link_libraries(fsw gcov)
121 target_link_libraries(fsw gcov)
116 SET_TARGET_PROPERTIES(fsw PROPERTIES COMPILE_FLAGS "-fprofile-arcs -ftest-coverage")
122 SET_TARGET_PROPERTIES(fsw PROPERTIES COMPILE_FLAGS "-fprofile-arcs -ftest-coverage")
117 endif()
123 endif()
118
124
119
125
120 if(fix-b2bst)
126 if(fix-b2bst)
121 check_b2bst(fsw ${CMAKE_CURRENT_BINARY_DIR})
127 check_b2bst(fsw ${CMAKE_CURRENT_BINARY_DIR})
122 endif()
128 endif()
123
129
124 if(NOT FSW_lpp_dpu_destid)
130 if(NOT FSW_lpp_dpu_destid)
125 build_srec(fsw ${CMAKE_CURRENT_BINARY_DIR} "${SW_VERSION_N1}-${SW_VERSION_N2}-${SW_VERSION_N3}-${SW_VERSION_N4}")
131 build_srec(fsw ${CMAKE_CURRENT_BINARY_DIR} "${SW_VERSION_N1}-${SW_VERSION_N2}-${SW_VERSION_N3}-${SW_VERSION_N4}")
126 endif()
132 endif()
127
133
128
134
129 #add_test_cppcheck(fsw STYLE UNUSED_FUNCTIONS POSSIBLE_ERROR MISSING_INCLUDE)
135 #add_test_cppcheck(fsw STYLE UNUSED_FUNCTIONS POSSIBLE_ERROR MISSING_INCLUDE)
130
136
@@ -1,1109 +1,1111
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW),
2 -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW),
3 -- This file is a part of the LFR FSW
3 -- This file is a part of the LFR FSW
4 -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS
4 -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS
5 --
5 --
6 -- This program is free software; you can redistribute it and/or modify
6 -- This program is free software; you can redistribute it and/or modify
7 -- it under the terms of the GNU General Public License as published by
7 -- it under the terms of the GNU General Public License as published by
8 -- the Free Software Foundation; either version 2 of the License, or
8 -- the Free Software Foundation; either version 2 of the License, or
9 -- (at your option) any later version.
9 -- (at your option) any later version.
10 --
10 --
11 -- This program is distributed in the hope that it will be useful,
11 -- This program is distributed in the hope that it will be useful,
12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 -- GNU General Public License for more details.
14 -- GNU General Public License for more details.
15 --
15 --
16 -- You should have received a copy of the GNU General Public License
16 -- You should have received a copy of the GNU General Public License
17 -- along with this program; if not, write to the Free Software
17 -- along with this program; if not, write to the Free Software
18 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 -------------------------------------------------------------------------------*/
19 -------------------------------------------------------------------------------*/
20 /*-- Author : Paul Leroy
20 /*-- Author : Paul Leroy
21 -- Contact : Alexis Jeandet
21 -- Contact : Alexis Jeandet
22 -- Mail : alexis.jeandet@lpp.polytechnique.fr
22 -- Mail : alexis.jeandet@lpp.polytechnique.fr
23 ----------------------------------------------------------------------------*/
23 ----------------------------------------------------------------------------*/
24
24
25 /** General usage functions and RTEMS tasks.
25 /** General usage functions and RTEMS tasks.
26 *
26 *
27 * @file
27 * @file
28 * @author P. LEROY
28 * @author P. LEROY
29 *
29 *
30 */
30 */
31
31
32 #include "fsw_misc.h"
32 #include "fsw_misc.h"
33
33
34 int16_t hk_lfr_sc_v_f3_as_int16 = 0;
34 int16_t hk_lfr_sc_v_f3_as_int16 = 0;
35 int16_t hk_lfr_sc_e1_f3_as_int16 = 0;
35 int16_t hk_lfr_sc_e1_f3_as_int16 = 0;
36 int16_t hk_lfr_sc_e2_f3_as_int16 = 0;
36 int16_t hk_lfr_sc_e2_f3_as_int16 = 0;
37
37
38 void timer_configure(unsigned char timer, unsigned int clock_divider,
38 void timer_configure(unsigned char timer, unsigned int clock_divider,
39 unsigned char interrupt_level, rtems_isr (*timer_isr)() )
39 unsigned char interrupt_level, rtems_isr (*timer_isr)() )
40 {
40 {
41 /** This function configures a GPTIMER timer instantiated in the VHDL design.
41 /** This function configures a GPTIMER timer instantiated in the VHDL design.
42 *
42 *
43 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
43 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
44 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
44 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
45 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
45 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
46 * @param interrupt_level is the interrupt level that the timer drives.
46 * @param interrupt_level is the interrupt level that the timer drives.
47 * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer.
47 * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer.
48 *
48 *
49 * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76
49 * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76
50 *
50 *
51 */
51 */
52
52
53 rtems_status_code status;
53 rtems_status_code status;
54 rtems_isr_entry old_isr_handler;
54 rtems_isr_entry old_isr_handler;
55
55
56 old_isr_handler = NULL;
56 old_isr_handler = NULL;
57
57
58 gptimer_regs->timer[timer].ctrl = INIT_CHAR; // reset the control register
58 gptimer_regs->timer[timer].ctrl = INIT_CHAR; // reset the control register
59
59
60 status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels
60 status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels
61 if (status!=RTEMS_SUCCESSFUL)
61 if (status!=RTEMS_SUCCESSFUL)
62 {
62 {
63 PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n")
63 PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n")
64 }
64 }
65
65
66 timer_set_clock_divider( timer, clock_divider);
66 timer_set_clock_divider( timer, clock_divider);
67 }
67 }
68
68
69 #ifdef ENABLE_DEAD_CODE
69 void timer_start(unsigned char timer)
70 void timer_start(unsigned char timer)
70 {
71 {
71 /** This function starts a GPTIMER timer.
72 /** This function starts a GPTIMER timer.
72 *
73 *
73 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
74 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
74 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
75 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
75 *
76 *
76 */
77 */
77
78
78 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_CLEAR_IRQ;
79 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_CLEAR_IRQ;
79 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_LD;
80 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_LD;
80 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_EN;
81 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_EN;
81 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_RS;
82 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_RS;
82 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_IE;
83 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_IE;
83 }
84 }
85 #endif
84
86
85 void timer_stop(unsigned char timer)
87 void timer_stop(unsigned char timer)
86 {
88 {
87 /** This function stops a GPTIMER timer.
89 /** This function stops a GPTIMER timer.
88 *
90 *
89 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
91 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
90 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
92 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
91 *
93 *
92 */
94 */
93
95
94 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & GPTIMER_EN_MASK;
96 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & GPTIMER_EN_MASK;
95 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & GPTIMER_IE_MASK;
97 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & GPTIMER_IE_MASK;
96 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_CLEAR_IRQ;
98 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_CLEAR_IRQ;
97 }
99 }
98
100
99 void timer_set_clock_divider(unsigned char timer, unsigned int clock_divider)
101 void timer_set_clock_divider(unsigned char timer, unsigned int clock_divider)
100 {
102 {
101 /** This function sets the clock divider of a GPTIMER timer.
103 /** This function sets the clock divider of a GPTIMER timer.
102 *
104 *
103 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
105 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
104 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
106 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
105 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
107 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
106 *
108 *
107 */
109 */
108
110
109 gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz
111 gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz
110 }
112 }
111
113
112 // WATCHDOG, this ISR should never be triggered.
114 // WATCHDOG, this ISR should never be triggered.
113
115
114 rtems_isr watchdog_isr( rtems_vector_number vector )
116 rtems_isr watchdog_isr( rtems_vector_number vector )
115 {
117 {
116 rtems_status_code status_code;
118 rtems_status_code status_code;
117
119
118 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_12 );
120 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_12 );
119
121
120 PRINTF("watchdog_isr *** this is the end, exit(0)\n");
122 PRINTF("watchdog_isr *** this is the end, exit(0)\n");
121
123
122 exit(0);
124 exit(0);
123 }
125 }
124
126
125 void watchdog_configure(void)
127 void watchdog_configure(void)
126 {
128 {
127 /** This function configure the watchdog.
129 /** This function configure the watchdog.
128 *
130 *
129 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
131 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
130 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
132 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
131 *
133 *
132 * The watchdog is a timer provided by the GPTIMER IP core of the GRLIB.
134 * The watchdog is a timer provided by the GPTIMER IP core of the GRLIB.
133 *
135 *
134 */
136 */
135
137
136 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt during configuration
138 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt during configuration
137
139
138 timer_configure( TIMER_WATCHDOG, CLKDIV_WATCHDOG, IRQ_SPARC_GPTIMER_WATCHDOG, watchdog_isr );
140 timer_configure( TIMER_WATCHDOG, CLKDIV_WATCHDOG, IRQ_SPARC_GPTIMER_WATCHDOG, watchdog_isr );
139
141
140 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
142 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
141 }
143 }
142
144
143 void watchdog_stop(void)
145 void watchdog_stop(void)
144 {
146 {
145 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt line
147 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt line
146 timer_stop( TIMER_WATCHDOG );
148 timer_stop( TIMER_WATCHDOG );
147 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
149 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
148 }
150 }
149
151
150 void watchdog_reload(void)
152 void watchdog_reload(void)
151 {
153 {
152 /** This function reloads the watchdog timer counter with the timer reload value.
154 /** This function reloads the watchdog timer counter with the timer reload value.
153 *
155 *
154 * @param void
156 * @param void
155 *
157 *
156 * @return void
158 * @return void
157 *
159 *
158 */
160 */
159
161
160 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_LD;
162 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_LD;
161 }
163 }
162
164
163 void watchdog_start(void)
165 void watchdog_start(void)
164 {
166 {
165 /** This function starts the watchdog timer.
167 /** This function starts the watchdog timer.
166 *
168 *
167 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
169 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
168 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
170 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
169 *
171 *
170 */
172 */
171
173
172 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG );
174 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG );
173
175
174 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_CLEAR_IRQ;
176 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_CLEAR_IRQ;
175 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_LD;
177 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_LD;
176 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_EN;
178 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_EN;
177 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_IE;
179 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_IE;
178
180
179 LEON_Unmask_interrupt( IRQ_GPTIMER_WATCHDOG );
181 LEON_Unmask_interrupt( IRQ_GPTIMER_WATCHDOG );
180
182
181 }
183 }
182
184
183 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
185 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
184 {
186 {
185 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
187 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
186
188
187 apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE;
189 apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE;
188
190
189 return 0;
191 return 0;
190 }
192 }
191
193
192 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
194 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
193 {
195 {
194 /** This function sets the scaler reload register of the apbuart module
196 /** This function sets the scaler reload register of the apbuart module
195 *
197 *
196 * @param regs is the address of the apbuart registers in memory
198 * @param regs is the address of the apbuart registers in memory
197 * @param value is the value that will be stored in the scaler register
199 * @param value is the value that will be stored in the scaler register
198 *
200 *
199 * The value shall be set by the software to get data on the serial interface.
201 * The value shall be set by the software to get data on the serial interface.
200 *
202 *
201 */
203 */
202
204
203 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
205 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
204
206
205 apbuart_regs->scaler = value;
207 apbuart_regs->scaler = value;
206
208
207 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
209 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
208 }
210 }
209
211
210 /**
212 /**
211 * @brief load_task starts and keeps the watchdog alive.
213 * @brief load_task starts and keeps the watchdog alive.
212 * @param argument
214 * @param argument
213 * @return
215 * @return
214 */
216 */
215
217
216 rtems_task load_task(rtems_task_argument argument)
218 rtems_task load_task(rtems_task_argument argument)
217 {
219 {
218 BOOT_PRINTF("in LOAD *** \n")
220 BOOT_PRINTF("in LOAD *** \n")
219
221
220 rtems_status_code status;
222 rtems_status_code status;
221 unsigned int i;
223 unsigned int i;
222 unsigned int j;
224 unsigned int j;
223 rtems_name name_watchdog_rate_monotonic; // name of the watchdog rate monotonic
225 rtems_name name_watchdog_rate_monotonic; // name of the watchdog rate monotonic
224 rtems_id watchdog_period_id; // id of the watchdog rate monotonic period
226 rtems_id watchdog_period_id; // id of the watchdog rate monotonic period
225
227
226 watchdog_period_id = RTEMS_ID_NONE;
228 watchdog_period_id = RTEMS_ID_NONE;
227
229
228 name_watchdog_rate_monotonic = rtems_build_name( 'L', 'O', 'A', 'D' );
230 name_watchdog_rate_monotonic = rtems_build_name( 'L', 'O', 'A', 'D' );
229
231
230 status = rtems_rate_monotonic_create( name_watchdog_rate_monotonic, &watchdog_period_id );
232 status = rtems_rate_monotonic_create( name_watchdog_rate_monotonic, &watchdog_period_id );
231 if( status != RTEMS_SUCCESSFUL ) {
233 if( status != RTEMS_SUCCESSFUL ) {
232 PRINTF1( "in LOAD *** rtems_rate_monotonic_create failed with status of %d\n", status )
234 PRINTF1( "in LOAD *** rtems_rate_monotonic_create failed with status of %d\n", status )
233 }
235 }
234
236
235 i = 0;
237 i = 0;
236 j = 0;
238 j = 0;
237
239
238 watchdog_configure();
240 watchdog_configure();
239
241
240 watchdog_start();
242 watchdog_start();
241
243
242 set_sy_lfr_watchdog_enabled( true );
244 set_sy_lfr_watchdog_enabled( true );
243
245
244 while(1){
246 while(1){
245 status = rtems_rate_monotonic_period( watchdog_period_id, WATCHDOG_PERIOD );
247 status = rtems_rate_monotonic_period( watchdog_period_id, WATCHDOG_PERIOD );
246 watchdog_reload();
248 watchdog_reload();
247 i = i + 1;
249 i = i + 1;
248 if ( i == WATCHDOG_LOOP_PRINTF )
250 if ( i == WATCHDOG_LOOP_PRINTF )
249 {
251 {
250 i = 0;
252 i = 0;
251 j = j + 1;
253 j = j + 1;
252 PRINTF1("%d\n", j)
254 PRINTF1("%d\n", j)
253 }
255 }
254 #ifdef DEBUG_WATCHDOG
256 #ifdef DEBUG_WATCHDOG
255 if (j == WATCHDOG_LOOP_DEBUG )
257 if (j == WATCHDOG_LOOP_DEBUG )
256 {
258 {
257 status = rtems_task_delete(RTEMS_SELF);
259 status = rtems_task_delete(RTEMS_SELF);
258 }
260 }
259 #endif
261 #endif
260 }
262 }
261 }
263 }
262
264
263 /**
265 /**
264 * @brief hous_task produces and sends HK each seconds
266 * @brief hous_task produces and sends HK each seconds
265 * @param argument
267 * @param argument
266 * @return
268 * @return
267 */
269 */
268 rtems_task hous_task(rtems_task_argument argument)
270 rtems_task hous_task(rtems_task_argument argument)
269 {
271 {
270 rtems_status_code status;
272 rtems_status_code status;
271 rtems_status_code spare_status;
273 rtems_status_code spare_status;
272 rtems_id queue_id;
274 rtems_id queue_id;
273 rtems_rate_monotonic_period_status period_status;
275 rtems_rate_monotonic_period_status period_status;
274 bool isSynchronized;
276 bool isSynchronized;
275
277
276 queue_id = RTEMS_ID_NONE;
278 queue_id = RTEMS_ID_NONE;
277 memset(&period_status, 0, sizeof(rtems_rate_monotonic_period_status));
279 memset(&period_status, 0, sizeof(rtems_rate_monotonic_period_status));
278 isSynchronized = false;
280 isSynchronized = false;
279
281
280 status = get_message_queue_id_send( &queue_id );
282 status = get_message_queue_id_send( &queue_id );
281 if (status != RTEMS_SUCCESSFUL)
283 if (status != RTEMS_SUCCESSFUL)
282 {
284 {
283 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
285 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
284 }
286 }
285
287
286 BOOT_PRINTF("in HOUS ***\n");
288 BOOT_PRINTF("in HOUS ***\n");
287
289
288 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
290 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
289 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
291 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
290 if( status != RTEMS_SUCCESSFUL ) {
292 if( status != RTEMS_SUCCESSFUL ) {
291 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status );
293 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status );
292 }
294 }
293 }
295 }
294
296
295 status = rtems_rate_monotonic_cancel(HK_id);
297 status = rtems_rate_monotonic_cancel(HK_id);
296 if( status != RTEMS_SUCCESSFUL ) {
298 if( status != RTEMS_SUCCESSFUL ) {
297 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status );
299 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status );
298 }
300 }
299 else {
301 else {
300 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n");
302 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n");
301 }
303 }
302
304
303 // startup phase
305 // startup phase
304 status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks );
306 status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks );
305 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
307 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
306 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
308 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
307 while( (period_status.state != RATE_MONOTONIC_EXPIRED)
309 while( (period_status.state != RATE_MONOTONIC_EXPIRED)
308 && (isSynchronized == false) ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway
310 && (isSynchronized == false) ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway
309 {
311 {
310 if ((time_management_regs->coarse_time & VAL_LFR_SYNCHRONIZED) == INT32_ALL_0) // check time synchronization
312 if ((time_management_regs->coarse_time & VAL_LFR_SYNCHRONIZED) == INT32_ALL_0) // check time synchronization
311 {
313 {
312 isSynchronized = true;
314 isSynchronized = true;
313 }
315 }
314 else
316 else
315 {
317 {
316 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
318 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
317
319
318 status = rtems_task_wake_after( HK_SYNC_WAIT ); // wait HK_SYNCH_WAIT 100 ms = 10 * 10 ms
320 status = rtems_task_wake_after( HK_SYNC_WAIT ); // wait HK_SYNCH_WAIT 100 ms = 10 * 10 ms
319 }
321 }
320 }
322 }
321 status = rtems_rate_monotonic_cancel(HK_id);
323 status = rtems_rate_monotonic_cancel(HK_id);
322 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
324 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
323
325
324 set_hk_lfr_reset_cause( POWER_ON );
326 set_hk_lfr_reset_cause( POWER_ON );
325
327
326 while(1){ // launch the rate monotonic task
328 while(1){ // launch the rate monotonic task
327 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
329 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
328 if ( status != RTEMS_SUCCESSFUL ) {
330 if ( status != RTEMS_SUCCESSFUL ) {
329 PRINTF1( "in HOUS *** ERR period: %d\n", status);
331 PRINTF1( "in HOUS *** ERR period: %d\n", status);
330 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
332 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
331 }
333 }
332 else {
334 else {
333 housekeeping_packet.packetSequenceControl[BYTE_0] = (unsigned char) (sequenceCounterHK >> SHIFT_1_BYTE);
335 housekeeping_packet.packetSequenceControl[BYTE_0] = (unsigned char) (sequenceCounterHK >> SHIFT_1_BYTE);
334 housekeeping_packet.packetSequenceControl[BYTE_1] = (unsigned char) (sequenceCounterHK );
336 housekeeping_packet.packetSequenceControl[BYTE_1] = (unsigned char) (sequenceCounterHK );
335 increment_seq_counter( &sequenceCounterHK );
337 increment_seq_counter( &sequenceCounterHK );
336
338
337 housekeeping_packet.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
339 housekeeping_packet.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
338 housekeeping_packet.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
340 housekeeping_packet.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
339 housekeeping_packet.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
341 housekeeping_packet.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
340 housekeeping_packet.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
342 housekeeping_packet.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
341 housekeeping_packet.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
343 housekeeping_packet.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
342 housekeeping_packet.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
344 housekeeping_packet.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
343
345
344 spacewire_update_hk_lfr_link_state( &housekeeping_packet.lfr_status_word[0] );
346 spacewire_update_hk_lfr_link_state( &housekeeping_packet.lfr_status_word[0] );
345
347
346 spacewire_read_statistics();
348 spacewire_read_statistics();
347
349
348 update_hk_with_grspw_stats();
350 update_hk_with_grspw_stats();
349
351
350 set_hk_lfr_time_not_synchro();
352 set_hk_lfr_time_not_synchro();
351
353
352 housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max;
354 housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max;
353 housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max;
355 housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max;
354 housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max;
356 housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max;
355 housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max;
357 housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max;
356 housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max;
358 housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max;
357
359
358 housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare;
360 housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare;
359 housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
361 housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
360 get_temperatures( housekeeping_packet.hk_lfr_temp_scm );
362 get_temperatures( housekeeping_packet.hk_lfr_temp_scm );
361 get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 );
363 get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 );
362 get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load );
364 get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load );
363
365
364 hk_lfr_le_me_he_update();
366 hk_lfr_le_me_he_update();
365
367
366 // SEND PACKET
368 // SEND PACKET
367 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
369 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
368 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
370 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
369 if (status != RTEMS_SUCCESSFUL) {
371 if (status != RTEMS_SUCCESSFUL) {
370 PRINTF1("in HOUS *** ERR send: %d\n", status)
372 PRINTF1("in HOUS *** ERR send: %d\n", status)
371 }
373 }
372 }
374 }
373 }
375 }
374
376
375 PRINTF("in HOUS *** deleting task\n")
377 PRINTF("in HOUS *** deleting task\n")
376
378
377 status = rtems_task_delete( RTEMS_SELF ); // should not return
379 status = rtems_task_delete( RTEMS_SELF ); // should not return
378
380
379 return;
381 return;
380 }
382 }
381
383
382 /**
384 /**
383 * @brief filter is a Direct-Form-II filter implementation, mostly used to filter electric field for HK
385 * @brief filter is a Direct-Form-II filter implementation, mostly used to filter electric field for HK
384 * @param x, new sample
386 * @param x, new sample
385 * @param ctx, filter context, used to store previous input and output samples
387 * @param ctx, filter context, used to store previous input and output samples
386 * @return a new filtered sample
388 * @return a new filtered sample
387 */
389 */
388 int filter( int x, filter_ctx* ctx )
390 int filter( int x, filter_ctx* ctx )
389 {
391 {
390 static const int b[NB_COEFFS][NB_COEFFS]={ {B00, B01, B02}, {B10, B11, B12}, {B20, B21, B22} };
392 static const int b[NB_COEFFS][NB_COEFFS]={ {B00, B01, B02}, {B10, B11, B12}, {B20, B21, B22} };
391 static const int a[NB_COEFFS][NB_COEFFS]={ {A00, A01, A02}, {A10, A11, A12}, {A20, A21, A22} };
393 static const int a[NB_COEFFS][NB_COEFFS]={ {A00, A01, A02}, {A10, A11, A12}, {A20, A21, A22} };
392 static const int b_gain[NB_COEFFS]={GAIN_B0, GAIN_B1, GAIN_B2};
394 static const int b_gain[NB_COEFFS]={GAIN_B0, GAIN_B1, GAIN_B2};
393 static const int a_gain[NB_COEFFS]={GAIN_A0, GAIN_A1, GAIN_A2};
395 static const int a_gain[NB_COEFFS]={GAIN_A0, GAIN_A1, GAIN_A2};
394
396
395 int_fast32_t W;
397 int_fast32_t W;
396 int i;
398 int i;
397
399
398 W = INIT_INT;
400 W = INIT_INT;
399 i = INIT_INT;
401 i = INIT_INT;
400
402
401 //Direct-Form-II
403 //Direct-Form-II
402 for ( i = 0; i < NB_COEFFS; i++ )
404 for ( i = 0; i < NB_COEFFS; i++ )
403 {
405 {
404 x = x << a_gain[i];
406 x = x << a_gain[i];
405 W = (x - ( a[i][COEFF1] * ctx->W[i][COEFF0] )
407 W = (x - ( a[i][COEFF1] * ctx->W[i][COEFF0] )
406 - ( a[i][COEFF2] * ctx->W[i][COEFF1] ) ) >> a_gain[i];
408 - ( a[i][COEFF2] * ctx->W[i][COEFF1] ) ) >> a_gain[i];
407 x = ( b[i][COEFF0] * W )
409 x = ( b[i][COEFF0] * W )
408 + ( b[i][COEFF1] * ctx->W[i][COEFF0] )
410 + ( b[i][COEFF1] * ctx->W[i][COEFF0] )
409 + ( b[i][COEFF2] * ctx->W[i][COEFF1] );
411 + ( b[i][COEFF2] * ctx->W[i][COEFF1] );
410 x = x >> b_gain[i];
412 x = x >> b_gain[i];
411 ctx->W[i][1] = ctx->W[i][0];
413 ctx->W[i][1] = ctx->W[i][0];
412 ctx->W[i][0] = W;
414 ctx->W[i][0] = W;
413 }
415 }
414 return x;
416 return x;
415 }
417 }
416
418
417 /**
419 /**
418 * @brief avgv_task pruduces HK rate elctrical field from F3 data
420 * @brief avgv_task pruduces HK rate elctrical field from F3 data
419 * @param argument
421 * @param argument
420 * @return
422 * @return
421 */
423 */
422 rtems_task avgv_task(rtems_task_argument argument)
424 rtems_task avgv_task(rtems_task_argument argument)
423 {
425 {
424 #define MOVING_AVERAGE 16
426 #define MOVING_AVERAGE 16
425 rtems_status_code status;
427 rtems_status_code status;
426 static int32_t v[MOVING_AVERAGE] = {0};
428 static int32_t v[MOVING_AVERAGE] = {0};
427 static int32_t e1[MOVING_AVERAGE] = {0};
429 static int32_t e1[MOVING_AVERAGE] = {0};
428 static int32_t e2[MOVING_AVERAGE] = {0};
430 static int32_t e2[MOVING_AVERAGE] = {0};
429 static int old_v = 0;
431 static int old_v = 0;
430 static int old_e1 = 0;
432 static int old_e1 = 0;
431 static int old_e2 = 0;
433 static int old_e2 = 0;
432 int32_t current_v;
434 int32_t current_v;
433 int32_t current_e1;
435 int32_t current_e1;
434 int32_t current_e2;
436 int32_t current_e2;
435 int32_t average_v;
437 int32_t average_v;
436 int32_t average_e1;
438 int32_t average_e1;
437 int32_t average_e2;
439 int32_t average_e2;
438 int32_t newValue_v;
440 int32_t newValue_v;
439 int32_t newValue_e1;
441 int32_t newValue_e1;
440 int32_t newValue_e2;
442 int32_t newValue_e2;
441 unsigned char k;
443 unsigned char k;
442 unsigned char indexOfOldValue;
444 unsigned char indexOfOldValue;
443
445
444 static filter_ctx ctx_v = { { {0,0,0}, {0,0,0}, {0,0,0} } };
446 static filter_ctx ctx_v = { { {0,0,0}, {0,0,0}, {0,0,0} } };
445 static filter_ctx ctx_e1 = { { {0,0,0}, {0,0,0}, {0,0,0} } };
447 static filter_ctx ctx_e1 = { { {0,0,0}, {0,0,0}, {0,0,0} } };
446 static filter_ctx ctx_e2 = { { {0,0,0}, {0,0,0}, {0,0,0} } };
448 static filter_ctx ctx_e2 = { { {0,0,0}, {0,0,0}, {0,0,0} } };
447
449
448 BOOT_PRINTF("in AVGV ***\n");
450 BOOT_PRINTF("in AVGV ***\n");
449
451
450 if (rtems_rate_monotonic_ident( name_avgv_rate_monotonic, &AVGV_id) != RTEMS_SUCCESSFUL) {
452 if (rtems_rate_monotonic_ident( name_avgv_rate_monotonic, &AVGV_id) != RTEMS_SUCCESSFUL) {
451 status = rtems_rate_monotonic_create( name_avgv_rate_monotonic, &AVGV_id );
453 status = rtems_rate_monotonic_create( name_avgv_rate_monotonic, &AVGV_id );
452 if( status != RTEMS_SUCCESSFUL ) {
454 if( status != RTEMS_SUCCESSFUL ) {
453 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status );
455 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status );
454 }
456 }
455 }
457 }
456
458
457 status = rtems_rate_monotonic_cancel(AVGV_id);
459 status = rtems_rate_monotonic_cancel(AVGV_id);
458 if( status != RTEMS_SUCCESSFUL ) {
460 if( status != RTEMS_SUCCESSFUL ) {
459 PRINTF1( "ERR *** in AVGV *** rtems_rate_monotonic_cancel(AVGV_id) ***code: %d\n", status );
461 PRINTF1( "ERR *** in AVGV *** rtems_rate_monotonic_cancel(AVGV_id) ***code: %d\n", status );
460 }
462 }
461 else {
463 else {
462 DEBUG_PRINTF("OK *** in AVGV *** rtems_rate_monotonic_cancel(AVGV_id)\n");
464 DEBUG_PRINTF("OK *** in AVGV *** rtems_rate_monotonic_cancel(AVGV_id)\n");
463 }
465 }
464
466
465 // initialize values
467 // initialize values
466 indexOfOldValue = MOVING_AVERAGE - 1;
468 indexOfOldValue = MOVING_AVERAGE - 1;
467 current_v = 0;
469 current_v = 0;
468 current_e1 = 0;
470 current_e1 = 0;
469 current_e2 = 0;
471 current_e2 = 0;
470 average_v = 0;
472 average_v = 0;
471 average_e1 = 0;
473 average_e1 = 0;
472 average_e2 = 0;
474 average_e2 = 0;
473 newValue_v = 0;
475 newValue_v = 0;
474 newValue_e1 = 0;
476 newValue_e1 = 0;
475 newValue_e2 = 0;
477 newValue_e2 = 0;
476
478
477 k = INIT_CHAR;
479 k = INIT_CHAR;
478
480
479 while(1)
481 while(1)
480 { // launch the rate monotonic task
482 { // launch the rate monotonic task
481 status = rtems_rate_monotonic_period( AVGV_id, AVGV_PERIOD );
483 status = rtems_rate_monotonic_period( AVGV_id, AVGV_PERIOD );
482 if ( status != RTEMS_SUCCESSFUL )
484 if ( status != RTEMS_SUCCESSFUL )
483 {
485 {
484 PRINTF1( "in AVGV *** ERR period: %d\n", status);
486 PRINTF1( "in AVGV *** ERR period: %d\n", status);
485 }
487 }
486 else
488 else
487 {
489 {
488 current_v = waveform_picker_regs->v;
490 current_v = waveform_picker_regs->v;
489 current_e1 = waveform_picker_regs->e1;
491 current_e1 = waveform_picker_regs->e1;
490 current_e2 = waveform_picker_regs->e2;
492 current_e2 = waveform_picker_regs->e2;
491 if ( (current_v != old_v)
493 if ( (current_v != old_v)
492 || (current_e1 != old_e1)
494 || (current_e1 != old_e1)
493 || (current_e2 != old_e2))
495 || (current_e2 != old_e2))
494 {
496 {
495 average_v = filter( current_v, &ctx_v );
497 average_v = filter( current_v, &ctx_v );
496 average_e1 = filter( current_e1, &ctx_e1 );
498 average_e1 = filter( current_e1, &ctx_e1 );
497 average_e2 = filter( current_e2, &ctx_e2 );
499 average_e2 = filter( current_e2, &ctx_e2 );
498
500
499 //update int16 values
501 //update int16 values
500 hk_lfr_sc_v_f3_as_int16 = (int16_t) average_v;
502 hk_lfr_sc_v_f3_as_int16 = (int16_t) average_v;
501 hk_lfr_sc_e1_f3_as_int16 = (int16_t) average_e1;
503 hk_lfr_sc_e1_f3_as_int16 = (int16_t) average_e1;
502 hk_lfr_sc_e2_f3_as_int16 = (int16_t) average_e2;
504 hk_lfr_sc_e2_f3_as_int16 = (int16_t) average_e2;
503 }
505 }
504 old_v = current_v;
506 old_v = current_v;
505 old_e1 = current_e1;
507 old_e1 = current_e1;
506 old_e2 = current_e2;
508 old_e2 = current_e2;
507 }
509 }
508 }
510 }
509
511
510 PRINTF("in AVGV *** deleting task\n");
512 PRINTF("in AVGV *** deleting task\n");
511
513
512 status = rtems_task_delete( RTEMS_SELF ); // should not return
514 status = rtems_task_delete( RTEMS_SELF ); // should not return
513
515
514 return;
516 return;
515 }
517 }
516
518
517 rtems_task dumb_task( rtems_task_argument unused )
519 rtems_task dumb_task( rtems_task_argument unused )
518 {
520 {
519 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
521 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
520 *
522 *
521 * @param unused is the starting argument of the RTEMS task
523 * @param unused is the starting argument of the RTEMS task
522 *
524 *
523 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
525 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
524 *
526 *
525 */
527 */
526
528
527 unsigned int i;
529 unsigned int i;
528 unsigned int intEventOut;
530 unsigned int intEventOut;
529 unsigned int coarse_time = 0;
531 unsigned int coarse_time = 0;
530 unsigned int fine_time = 0;
532 unsigned int fine_time = 0;
531 rtems_event_set event_out;
533 rtems_event_set event_out;
532
534
533 event_out = EVENT_SETS_NONE_PENDING;
535 event_out = EVENT_SETS_NONE_PENDING;
534
536
535 BOOT_PRINTF("in DUMB *** \n")
537 BOOT_PRINTF("in DUMB *** \n")
536
538
537 while(1){
539 while(1){
538 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
540 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
539 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7
541 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7
540 | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12 | RTEMS_EVENT_13
542 | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12 | RTEMS_EVENT_13
541 | RTEMS_EVENT_14,
543 | RTEMS_EVENT_14,
542 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
544 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
543 intEventOut = (unsigned int) event_out;
545 intEventOut = (unsigned int) event_out;
544 for ( i=0; i<NB_RTEMS_EVENTS; i++)
546 for ( i=0; i<NB_RTEMS_EVENTS; i++)
545 {
547 {
546 if ( ((intEventOut >> i) & 1) != 0)
548 if ( ((intEventOut >> i) & 1) != 0)
547 {
549 {
548 coarse_time = time_management_regs->coarse_time;
550 coarse_time = time_management_regs->coarse_time;
549 fine_time = time_management_regs->fine_time;
551 fine_time = time_management_regs->fine_time;
550 if (i==EVENT_12)
552 if (i==EVENT_12)
551 {
553 {
552 PRINTF1("%s\n", DUMB_MESSAGE_12)
554 PRINTF1("%s\n", DUMB_MESSAGE_12)
553 }
555 }
554 if (i==EVENT_13)
556 if (i==EVENT_13)
555 {
557 {
556 PRINTF1("%s\n", DUMB_MESSAGE_13)
558 PRINTF1("%s\n", DUMB_MESSAGE_13)
557 }
559 }
558 if (i==EVENT_14)
560 if (i==EVENT_14)
559 {
561 {
560 PRINTF1("%s\n", DUMB_MESSAGE_1)
562 PRINTF1("%s\n", DUMB_MESSAGE_1)
561 }
563 }
562 }
564 }
563 }
565 }
564 }
566 }
565 }
567 }
566
568
567 rtems_task scrubbing_task( rtems_task_argument unused )
569 rtems_task scrubbing_task( rtems_task_argument unused )
568 {
570 {
569 /** This RTEMS taks is used to avoid entering IDLE task and also scrub memory to increase scubbing frequency.
571 /** This RTEMS taks is used to avoid entering IDLE task and also scrub memory to increase scubbing frequency.
570 *
572 *
571 * @param unused is the starting argument of the RTEMS task
573 * @param unused is the starting argument of the RTEMS task
572 *
574 *
573 * The scrubbing reads continuously memory when no other tasks are ready.
575 * The scrubbing reads continuously memory when no other tasks are ready.
574 *
576 *
575 */
577 */
576
578
577 BOOT_PRINTF("in SCRUBBING *** \n");
579 BOOT_PRINTF("in SCRUBBING *** \n");
578 volatile int i=0;
580 volatile int i=0;
579 volatile float valuef = 1.;
581 volatile float valuef = 1.;
580 volatile uint32_t* RAM=(uint32_t*)0x40000000;
582 volatile uint32_t* RAM=(uint32_t*)0x40000000;
581 volatile uint32_t value;
583 volatile uint32_t value;
582 #ifdef ENABLE_SCRUBBING_COUNTER
584 #ifdef ENABLE_SCRUBBING_COUNTER
583 housekeeping_packet.lfr_fpga_version[BYTE_0] = 0;
585 housekeeping_packet.lfr_fpga_version[BYTE_0] = 0;
584 #endif
586 #endif
585 while(1){
587 while(1){
586 i=(i+1)%(1024*1024);
588 i=(i+1)%(1024*1024);
587 valuef += 10.f*(float)RAM[i];
589 valuef += 10.f*(float)RAM[i];
588 #ifdef ENABLE_SCRUBBING_COUNTER
590 #ifdef ENABLE_SCRUBBING_COUNTER
589 if(i==0)
591 if(i==0)
590 {
592 {
591 housekeeping_packet.lfr_fpga_version[BYTE_0] += 1;
593 housekeeping_packet.lfr_fpga_version[BYTE_0] += 1;
592 }
594 }
593 #endif
595 #endif
594 }
596 }
595 }
597 }
596
598
597 rtems_task calibration_sweep_task( rtems_task_argument unused )
599 rtems_task calibration_sweep_task( rtems_task_argument unused )
598 {
600 {
599 /** This RTEMS taks is used to change calibration signal smapling frequency between snapshots.
601 /** This RTEMS taks is used to change calibration signal smapling frequency between snapshots.
600 *
602 *
601 * @param unused is the starting argument of the RTEMS task
603 * @param unused is the starting argument of the RTEMS task
602 *
604 *
603 * If calibration is enabled, this task will divide by two the calibration signal smapling frequency between snapshots.
605 * If calibration is enabled, this task will divide by two the calibration signal smapling frequency between snapshots.
604 * When minimum sampling frequency is reach it will jump to maximum sampling frequency to loop indefinitely.
606 * When minimum sampling frequency is reach it will jump to maximum sampling frequency to loop indefinitely.
605 *
607 *
606 */
608 */
607 rtems_event_set event_out;
609 rtems_event_set event_out;
608 BOOT_PRINTF("in calibration sweep *** \n");
610 BOOT_PRINTF("in calibration sweep *** \n");
609 rtems_interval ticks_per_seconds = rtems_clock_get_ticks_per_second();
611 rtems_interval ticks_per_seconds = rtems_clock_get_ticks_per_second();
610 while(1){
612 while(1){
611 // Waiting for next F0 snapshot
613 // Waiting for next F0 snapshot
612 rtems_event_receive(RTEMS_EVENT_CAL_SWEEP_WAKE, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out);
614 rtems_event_receive(RTEMS_EVENT_CAL_SWEEP_WAKE, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out);
613 if(time_management_regs->calDACCtrl & BIT_CAL_ENABLE)
615 if(time_management_regs->calDACCtrl & BIT_CAL_ENABLE)
614 {
616 {
615 unsigned int delta_snapshot;
617 unsigned int delta_snapshot;
616 delta_snapshot = (parameter_dump_packet.sy_lfr_n_swf_p[0] * CONST_256)
618 delta_snapshot = (parameter_dump_packet.sy_lfr_n_swf_p[0] * CONST_256)
617 + parameter_dump_packet.sy_lfr_n_swf_p[1];
619 + parameter_dump_packet.sy_lfr_n_swf_p[1];
618 // We are woken almost in the center of a snapshot -> let's wait for sy_lfr_n_swf_p / 2
620 // We are woken almost in the center of a snapshot -> let's wait for sy_lfr_n_swf_p / 2
619 rtems_task_wake_after( ticks_per_seconds * delta_snapshot / 2);
621 rtems_task_wake_after( ticks_per_seconds * delta_snapshot / 2);
620 if(time_management_regs->calDivisor >= CAL_F_DIVISOR_MAX){
622 if(time_management_regs->calDivisor >= CAL_F_DIVISOR_MAX){
621 time_management_regs->calDivisor = CAL_F_DIVISOR_MIN;
623 time_management_regs->calDivisor = CAL_F_DIVISOR_MIN;
622 }
624 }
623 else{
625 else{
624 time_management_regs->calDivisor *= 2;
626 time_management_regs->calDivisor *= 2;
625 }
627 }
626 }
628 }
627
629
628
630
629
631
630 }
632 }
631
633
632 }
634 }
633
635
634
636
635 //*****************************
637 //*****************************
636 // init housekeeping parameters
638 // init housekeeping parameters
637
639
638 void init_housekeeping_parameters( void )
640 void init_housekeeping_parameters( void )
639 {
641 {
640 /** This function initialize the housekeeping_packet global variable with default values.
642 /** This function initialize the housekeeping_packet global variable with default values.
641 *
643 *
642 */
644 */
643
645
644 unsigned int i = 0;
646 unsigned int i = 0;
645 unsigned char *parameters;
647 unsigned char *parameters;
646 unsigned char sizeOfHK;
648 unsigned char sizeOfHK;
647
649
648 sizeOfHK = sizeof( Packet_TM_LFR_HK_t );
650 sizeOfHK = sizeof( Packet_TM_LFR_HK_t );
649
651
650 parameters = (unsigned char*) &housekeeping_packet;
652 parameters = (unsigned char*) &housekeeping_packet;
651
653
652 for(i = 0; i< sizeOfHK; i++)
654 for(i = 0; i< sizeOfHK; i++)
653 {
655 {
654 parameters[i] = INIT_CHAR;
656 parameters[i] = INIT_CHAR;
655 }
657 }
656
658
657 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
659 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
658 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
660 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
659 housekeeping_packet.reserved = DEFAULT_RESERVED;
661 housekeeping_packet.reserved = DEFAULT_RESERVED;
660 housekeeping_packet.userApplication = CCSDS_USER_APP;
662 housekeeping_packet.userApplication = CCSDS_USER_APP;
661 housekeeping_packet.packetID[0] = (unsigned char) (APID_TM_HK >> SHIFT_1_BYTE);
663 housekeeping_packet.packetID[0] = (unsigned char) (APID_TM_HK >> SHIFT_1_BYTE);
662 housekeeping_packet.packetID[1] = (unsigned char) (APID_TM_HK);
664 housekeeping_packet.packetID[1] = (unsigned char) (APID_TM_HK);
663 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
665 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
664 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
666 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
665 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> SHIFT_1_BYTE);
667 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> SHIFT_1_BYTE);
666 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
668 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
667 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
669 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
668 housekeeping_packet.serviceType = TM_TYPE_HK;
670 housekeeping_packet.serviceType = TM_TYPE_HK;
669 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
671 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
670 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
672 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
671 housekeeping_packet.sid = SID_HK;
673 housekeeping_packet.sid = SID_HK;
672
674
673 // init status word
675 // init status word
674 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
676 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
675 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
677 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
676 // init software version
678 // init software version
677 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
679 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
678 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
680 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
679 housekeeping_packet.lfr_sw_version[BYTE_2] = SW_VERSION_N3;
681 housekeeping_packet.lfr_sw_version[BYTE_2] = SW_VERSION_N3;
680 housekeeping_packet.lfr_sw_version[BYTE_3] = SW_VERSION_N4;
682 housekeeping_packet.lfr_sw_version[BYTE_3] = SW_VERSION_N4;
681 // init fpga version
683 // init fpga version
682 parameters = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
684 parameters = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
683 housekeeping_packet.lfr_fpga_version[BYTE_0] = parameters[BYTE_1]; // n1
685 housekeeping_packet.lfr_fpga_version[BYTE_0] = parameters[BYTE_1]; // n1
684 housekeeping_packet.lfr_fpga_version[BYTE_1] = parameters[BYTE_2]; // n2
686 housekeeping_packet.lfr_fpga_version[BYTE_1] = parameters[BYTE_2]; // n2
685 housekeeping_packet.lfr_fpga_version[BYTE_2] = parameters[BYTE_3]; // n3
687 housekeeping_packet.lfr_fpga_version[BYTE_2] = parameters[BYTE_3]; // n3
686
688
687 housekeeping_packet.hk_lfr_q_sd_fifo_size = MSG_QUEUE_COUNT_SEND;
689 housekeeping_packet.hk_lfr_q_sd_fifo_size = MSG_QUEUE_COUNT_SEND;
688 housekeeping_packet.hk_lfr_q_rv_fifo_size = MSG_QUEUE_COUNT_RECV;
690 housekeeping_packet.hk_lfr_q_rv_fifo_size = MSG_QUEUE_COUNT_RECV;
689 housekeeping_packet.hk_lfr_q_p0_fifo_size = MSG_QUEUE_COUNT_PRC0;
691 housekeeping_packet.hk_lfr_q_p0_fifo_size = MSG_QUEUE_COUNT_PRC0;
690 housekeeping_packet.hk_lfr_q_p1_fifo_size = MSG_QUEUE_COUNT_PRC1;
692 housekeeping_packet.hk_lfr_q_p1_fifo_size = MSG_QUEUE_COUNT_PRC1;
691 housekeeping_packet.hk_lfr_q_p2_fifo_size = MSG_QUEUE_COUNT_PRC2;
693 housekeeping_packet.hk_lfr_q_p2_fifo_size = MSG_QUEUE_COUNT_PRC2;
692 }
694 }
693
695
694 void increment_seq_counter( unsigned short *packetSequenceControl )
696 void increment_seq_counter( unsigned short *packetSequenceControl )
695 {
697 {
696 /** This function increment the sequence counter passes in argument.
698 /** This function increment the sequence counter passes in argument.
697 *
699 *
698 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
700 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
699 *
701 *
700 */
702 */
701
703
702 unsigned short segmentation_grouping_flag;
704 unsigned short segmentation_grouping_flag;
703 unsigned short sequence_cnt;
705 unsigned short sequence_cnt;
704
706
705 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << SHIFT_1_BYTE; // keep bits 7 downto 6
707 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << SHIFT_1_BYTE; // keep bits 7 downto 6
706 sequence_cnt = (*packetSequenceControl) & SEQ_CNT_MASK; // [0011 1111 1111 1111]
708 sequence_cnt = (*packetSequenceControl) & SEQ_CNT_MASK; // [0011 1111 1111 1111]
707
709
708 if ( sequence_cnt < SEQ_CNT_MAX)
710 if ( sequence_cnt < SEQ_CNT_MAX)
709 {
711 {
710 sequence_cnt = sequence_cnt + 1;
712 sequence_cnt = sequence_cnt + 1;
711 }
713 }
712 else
714 else
713 {
715 {
714 sequence_cnt = 0;
716 sequence_cnt = 0;
715 }
717 }
716
718
717 *packetSequenceControl = segmentation_grouping_flag | sequence_cnt ;
719 *packetSequenceControl = segmentation_grouping_flag | sequence_cnt ;
718 }
720 }
719
721
720 void getTime( unsigned char *time)
722 void getTime( unsigned char *time)
721 {
723 {
722 /** This function write the current local time in the time buffer passed in argument.
724 /** This function write the current local time in the time buffer passed in argument.
723 *
725 *
724 */
726 */
725
727
726 time[0] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_3_BYTES);
728 time[0] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_3_BYTES);
727 time[1] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_2_BYTES);
729 time[1] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_2_BYTES);
728 time[2] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_1_BYTE);
730 time[2] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_1_BYTE);
729 time[3] = (unsigned char) (time_management_regs->coarse_time);
731 time[3] = (unsigned char) (time_management_regs->coarse_time);
730 time[4] = (unsigned char) (time_management_regs->fine_time>>SHIFT_1_BYTE);
732 time[4] = (unsigned char) (time_management_regs->fine_time>>SHIFT_1_BYTE);
731 time[5] = (unsigned char) (time_management_regs->fine_time);
733 time[5] = (unsigned char) (time_management_regs->fine_time);
732 }
734 }
733
735
734 unsigned long long int getTimeAsUnsignedLongLongInt( )
736 unsigned long long int getTimeAsUnsignedLongLongInt( )
735 {
737 {
736 /** This function write the current local time in the time buffer passed in argument.
738 /** This function write the current local time in the time buffer passed in argument.
737 *
739 *
738 */
740 */
739 unsigned long long int time;
741 unsigned long long int time;
740
742
741 time = ( (unsigned long long int) (time_management_regs->coarse_time & COARSE_TIME_MASK) << SHIFT_2_BYTES )
743 time = ( (unsigned long long int) (time_management_regs->coarse_time & COARSE_TIME_MASK) << SHIFT_2_BYTES )
742 + time_management_regs->fine_time;
744 + time_management_regs->fine_time;
743
745
744 return time;
746 return time;
745 }
747 }
746
748
747 void get_temperatures( unsigned char *temperatures )
749 void get_temperatures( unsigned char *temperatures )
748 {
750 {
749 unsigned char* temp_scm_ptr;
751 unsigned char* temp_scm_ptr;
750 unsigned char* temp_pcb_ptr;
752 unsigned char* temp_pcb_ptr;
751 unsigned char* temp_fpga_ptr;
753 unsigned char* temp_fpga_ptr;
752
754
753 // SEL1 SEL0
755 // SEL1 SEL0
754 // 0 0 => PCB
756 // 0 0 => PCB
755 // 0 1 => FPGA
757 // 0 1 => FPGA
756 // 1 0 => SCM
758 // 1 0 => SCM
757
759
758 temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm;
760 temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm;
759 temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb;
761 temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb;
760 temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga;
762 temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga;
761
763
762 temperatures[ BYTE_0 ] = temp_scm_ptr[ BYTE_2 ];
764 temperatures[ BYTE_0 ] = temp_scm_ptr[ BYTE_2 ];
763 temperatures[ BYTE_1 ] = temp_scm_ptr[ BYTE_3 ];
765 temperatures[ BYTE_1 ] = temp_scm_ptr[ BYTE_3 ];
764 temperatures[ BYTE_2 ] = temp_pcb_ptr[ BYTE_2 ];
766 temperatures[ BYTE_2 ] = temp_pcb_ptr[ BYTE_2 ];
765 temperatures[ BYTE_3 ] = temp_pcb_ptr[ BYTE_3 ];
767 temperatures[ BYTE_3 ] = temp_pcb_ptr[ BYTE_3 ];
766 temperatures[ BYTE_4 ] = temp_fpga_ptr[ BYTE_2 ];
768 temperatures[ BYTE_4 ] = temp_fpga_ptr[ BYTE_2 ];
767 temperatures[ BYTE_5 ] = temp_fpga_ptr[ BYTE_3 ];
769 temperatures[ BYTE_5 ] = temp_fpga_ptr[ BYTE_3 ];
768 }
770 }
769
771
770 void get_v_e1_e2_f3( unsigned char *spacecraft_potential )
772 void get_v_e1_e2_f3( unsigned char *spacecraft_potential )
771 {
773 {
772 unsigned char* v_ptr;
774 unsigned char* v_ptr;
773 unsigned char* e1_ptr;
775 unsigned char* e1_ptr;
774 unsigned char* e2_ptr;
776 unsigned char* e2_ptr;
775
777
776 v_ptr = (unsigned char *) &hk_lfr_sc_v_f3_as_int16;
778 v_ptr = (unsigned char *) &hk_lfr_sc_v_f3_as_int16;
777 e1_ptr = (unsigned char *) &hk_lfr_sc_e1_f3_as_int16;
779 e1_ptr = (unsigned char *) &hk_lfr_sc_e1_f3_as_int16;
778 e2_ptr = (unsigned char *) &hk_lfr_sc_e2_f3_as_int16;
780 e2_ptr = (unsigned char *) &hk_lfr_sc_e2_f3_as_int16;
779
781
780 spacecraft_potential[BYTE_0] = v_ptr[0];
782 spacecraft_potential[BYTE_0] = v_ptr[0];
781 spacecraft_potential[BYTE_1] = v_ptr[1];
783 spacecraft_potential[BYTE_1] = v_ptr[1];
782 spacecraft_potential[BYTE_2] = e1_ptr[0];
784 spacecraft_potential[BYTE_2] = e1_ptr[0];
783 spacecraft_potential[BYTE_3] = e1_ptr[1];
785 spacecraft_potential[BYTE_3] = e1_ptr[1];
784 spacecraft_potential[BYTE_4] = e2_ptr[0];
786 spacecraft_potential[BYTE_4] = e2_ptr[0];
785 spacecraft_potential[BYTE_5] = e2_ptr[1];
787 spacecraft_potential[BYTE_5] = e2_ptr[1];
786 }
788 }
787
789
788 /**
790 /**
789 * @brief get_cpu_load, computes CPU load, CPU load average and CPU load max
791 * @brief get_cpu_load, computes CPU load, CPU load average and CPU load max
790 * @param resource_statistics stores:
792 * @param resource_statistics stores:
791 * - CPU load at index 0
793 * - CPU load at index 0
792 * - CPU load max at index 1
794 * - CPU load max at index 1
793 * - CPU load average at index 2
795 * - CPU load average at index 2
794 *
796 *
795 * The CPU load average is computed on the last 60 values with a simple moving average.
797 * The CPU load average is computed on the last 60 values with a simple moving average.
796 */
798 */
797 void get_cpu_load( unsigned char *resource_statistics )
799 void get_cpu_load( unsigned char *resource_statistics )
798 {
800 {
799 #define LOAD_AVG_SIZE 60
801 #define LOAD_AVG_SIZE 60
800 static unsigned char cpu_load_hist[LOAD_AVG_SIZE]={0};
802 static unsigned char cpu_load_hist[LOAD_AVG_SIZE]={0};
801 static char old_avg_pos=0;
803 static char old_avg_pos=0;
802 static unsigned int cpu_load_avg;
804 static unsigned int cpu_load_avg;
803 unsigned char cpu_load;
805 unsigned char cpu_load;
804
806
805 cpu_load = lfr_rtems_cpu_usage_report();
807 cpu_load = lfr_rtems_cpu_usage_report();
806
808
807 // HK_LFR_CPU_LOAD
809 // HK_LFR_CPU_LOAD
808 resource_statistics[BYTE_0] = cpu_load;
810 resource_statistics[BYTE_0] = cpu_load;
809
811
810 // HK_LFR_CPU_LOAD_MAX
812 // HK_LFR_CPU_LOAD_MAX
811 if (cpu_load > resource_statistics[BYTE_1])
813 if (cpu_load > resource_statistics[BYTE_1])
812 {
814 {
813 resource_statistics[BYTE_1] = cpu_load;
815 resource_statistics[BYTE_1] = cpu_load;
814 }
816 }
815
817
816 cpu_load_avg = cpu_load_avg - (unsigned int)cpu_load_hist[(int)old_avg_pos] + (unsigned int)cpu_load;
818 cpu_load_avg = cpu_load_avg - (unsigned int)cpu_load_hist[(int)old_avg_pos] + (unsigned int)cpu_load;
817 cpu_load_hist[(int)old_avg_pos] = cpu_load;
819 cpu_load_hist[(int)old_avg_pos] = cpu_load;
818 old_avg_pos += 1;
820 old_avg_pos += 1;
819 old_avg_pos %= LOAD_AVG_SIZE;
821 old_avg_pos %= LOAD_AVG_SIZE;
820 // CPU_LOAD_AVE
822 // CPU_LOAD_AVE
821 resource_statistics[BYTE_2] = (unsigned char)(cpu_load_avg / LOAD_AVG_SIZE);
823 resource_statistics[BYTE_2] = (unsigned char)(cpu_load_avg / LOAD_AVG_SIZE);
822 // this will change the way LFR compute usage
824 // this will change the way LFR compute usage
823 #ifndef PRINT_TASK_STATISTICS
825 #ifndef PRINT_TASK_STATISTICS
824 rtems_cpu_usage_reset();
826 rtems_cpu_usage_reset();
825 #endif
827 #endif
826
828
827 }
829 }
828
830
829 void set_hk_lfr_sc_potential_flag( bool state )
831 void set_hk_lfr_sc_potential_flag( bool state )
830 {
832 {
831 if (state == true)
833 if (state == true)
832 {
834 {
833 housekeeping_packet.lfr_status_word[1] =
835 housekeeping_packet.lfr_status_word[1] =
834 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_SC_POTENTIAL_FLAG_BIT; // [0100 0000]
836 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_SC_POTENTIAL_FLAG_BIT; // [0100 0000]
835 }
837 }
836 else
838 else
837 {
839 {
838 housekeeping_packet.lfr_status_word[1] =
840 housekeeping_packet.lfr_status_word[1] =
839 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_SC_POTENTIAL_FLAG_MASK; // [1011 1111]
841 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_SC_POTENTIAL_FLAG_MASK; // [1011 1111]
840 }
842 }
841 }
843 }
842
844
843 void set_sy_lfr_pas_filter_enabled( bool state )
845 void set_sy_lfr_pas_filter_enabled( bool state )
844 {
846 {
845 if (state == true)
847 if (state == true)
846 {
848 {
847 housekeeping_packet.lfr_status_word[1] =
849 housekeeping_packet.lfr_status_word[1] =
848 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_PAS_FILTER_ENABLED_BIT; // [0010 0000]
850 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_PAS_FILTER_ENABLED_BIT; // [0010 0000]
849 }
851 }
850 else
852 else
851 {
853 {
852 housekeeping_packet.lfr_status_word[1] =
854 housekeeping_packet.lfr_status_word[1] =
853 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_PAS_FILTER_ENABLED_MASK; // [1101 1111]
855 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_PAS_FILTER_ENABLED_MASK; // [1101 1111]
854 }
856 }
855 }
857 }
856
858
857 void set_sy_lfr_watchdog_enabled( bool state )
859 void set_sy_lfr_watchdog_enabled( bool state )
858 {
860 {
859 if (state == true)
861 if (state == true)
860 {
862 {
861 housekeeping_packet.lfr_status_word[1] =
863 housekeeping_packet.lfr_status_word[1] =
862 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_WATCHDOG_BIT; // [0001 0000]
864 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_WATCHDOG_BIT; // [0001 0000]
863 }
865 }
864 else
866 else
865 {
867 {
866 housekeeping_packet.lfr_status_word[1] =
868 housekeeping_packet.lfr_status_word[1] =
867 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_WATCHDOG_MASK; // [1110 1111]
869 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_WATCHDOG_MASK; // [1110 1111]
868 }
870 }
869 }
871 }
870
872
871 void set_hk_lfr_calib_enable( bool state )
873 void set_hk_lfr_calib_enable( bool state )
872 {
874 {
873 if (state == true)
875 if (state == true)
874 {
876 {
875 housekeeping_packet.lfr_status_word[1] =
877 housekeeping_packet.lfr_status_word[1] =
876 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_CALIB_BIT; // [0000 1000]
878 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_CALIB_BIT; // [0000 1000]
877 }
879 }
878 else
880 else
879 {
881 {
880 housekeeping_packet.lfr_status_word[1] =
882 housekeeping_packet.lfr_status_word[1] =
881 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_CALIB_MASK; // [1111 0111]
883 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_CALIB_MASK; // [1111 0111]
882 }
884 }
883 }
885 }
884
886
885 void set_hk_lfr_reset_cause( enum lfr_reset_cause_t lfr_reset_cause )
887 void set_hk_lfr_reset_cause( enum lfr_reset_cause_t lfr_reset_cause )
886 {
888 {
887 housekeeping_packet.lfr_status_word[1] =
889 housekeeping_packet.lfr_status_word[1] =
888 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_RESET_CAUSE_MASK; // [1111 1000]
890 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_RESET_CAUSE_MASK; // [1111 1000]
889
891
890 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1]
892 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1]
891 | (lfr_reset_cause & STATUS_WORD_RESET_CAUSE_BITS ); // [0000 0111]
893 | (lfr_reset_cause & STATUS_WORD_RESET_CAUSE_BITS ); // [0000 0111]
892
894
893 }
895 }
894
896
895 void increment_hk_counter( unsigned char newValue, unsigned char oldValue, unsigned int *counter )
897 void increment_hk_counter( unsigned char newValue, unsigned char oldValue, unsigned int *counter )
896 {
898 {
897 int delta;
899 int delta;
898
900
899 delta = 0;
901 delta = 0;
900
902
901 if (newValue >= oldValue)
903 if (newValue >= oldValue)
902 {
904 {
903 delta = newValue - oldValue;
905 delta = newValue - oldValue;
904 }
906 }
905 else
907 else
906 {
908 {
907 delta = (CONST_256 - oldValue) + newValue;
909 delta = (CONST_256 - oldValue) + newValue;
908 }
910 }
909
911
910 *counter = *counter + delta;
912 *counter = *counter + delta;
911 }
913 }
912
914
913 // Low severity error counters update
915 // Low severity error counters update
914 void hk_lfr_le_update( void )
916 void hk_lfr_le_update( void )
915 {
917 {
916 static hk_lfr_le_t old_hk_lfr_le = {0};
918 static hk_lfr_le_t old_hk_lfr_le = {0};
917 hk_lfr_le_t new_hk_lfr_le;
919 hk_lfr_le_t new_hk_lfr_le;
918 unsigned int counter;
920 unsigned int counter;
919
921
920 counter = (((unsigned int) housekeeping_packet.hk_lfr_le_cnt[0]) * CONST_256) + housekeeping_packet.hk_lfr_le_cnt[1];
922 counter = (((unsigned int) housekeeping_packet.hk_lfr_le_cnt[0]) * CONST_256) + housekeeping_packet.hk_lfr_le_cnt[1];
921
923
922 // DPU
924 // DPU
923 new_hk_lfr_le.dpu_spw_parity = housekeeping_packet.hk_lfr_dpu_spw_parity;
925 new_hk_lfr_le.dpu_spw_parity = housekeeping_packet.hk_lfr_dpu_spw_parity;
924 new_hk_lfr_le.dpu_spw_disconnect= housekeeping_packet.hk_lfr_dpu_spw_disconnect;
926 new_hk_lfr_le.dpu_spw_disconnect= housekeeping_packet.hk_lfr_dpu_spw_disconnect;
925 new_hk_lfr_le.dpu_spw_escape = housekeeping_packet.hk_lfr_dpu_spw_escape;
927 new_hk_lfr_le.dpu_spw_escape = housekeeping_packet.hk_lfr_dpu_spw_escape;
926 new_hk_lfr_le.dpu_spw_credit = housekeeping_packet.hk_lfr_dpu_spw_credit;
928 new_hk_lfr_le.dpu_spw_credit = housekeeping_packet.hk_lfr_dpu_spw_credit;
927 new_hk_lfr_le.dpu_spw_write_sync= housekeeping_packet.hk_lfr_dpu_spw_write_sync;
929 new_hk_lfr_le.dpu_spw_write_sync= housekeeping_packet.hk_lfr_dpu_spw_write_sync;
928 // TIMECODE
930 // TIMECODE
929 new_hk_lfr_le.timecode_erroneous= housekeeping_packet.hk_lfr_timecode_erroneous;
931 new_hk_lfr_le.timecode_erroneous= housekeeping_packet.hk_lfr_timecode_erroneous;
930 new_hk_lfr_le.timecode_missing = housekeeping_packet.hk_lfr_timecode_missing;
932 new_hk_lfr_le.timecode_missing = housekeeping_packet.hk_lfr_timecode_missing;
931 new_hk_lfr_le.timecode_invalid = housekeeping_packet.hk_lfr_timecode_invalid;
933 new_hk_lfr_le.timecode_invalid = housekeeping_packet.hk_lfr_timecode_invalid;
932 // TIME
934 // TIME
933 new_hk_lfr_le.time_timecode_it = housekeeping_packet.hk_lfr_time_timecode_it;
935 new_hk_lfr_le.time_timecode_it = housekeeping_packet.hk_lfr_time_timecode_it;
934 new_hk_lfr_le.time_not_synchro = housekeeping_packet.hk_lfr_time_not_synchro;
936 new_hk_lfr_le.time_not_synchro = housekeeping_packet.hk_lfr_time_not_synchro;
935 new_hk_lfr_le.time_timecode_ctr = housekeeping_packet.hk_lfr_time_timecode_ctr;
937 new_hk_lfr_le.time_timecode_ctr = housekeeping_packet.hk_lfr_time_timecode_ctr;
936 //AHB
938 //AHB
937 new_hk_lfr_le.ahb_correctable = housekeeping_packet.hk_lfr_ahb_correctable;
939 new_hk_lfr_le.ahb_correctable = housekeeping_packet.hk_lfr_ahb_correctable;
938 // housekeeping_packet.hk_lfr_dpu_spw_rx_ahb => not handled by the grspw driver
940 // housekeeping_packet.hk_lfr_dpu_spw_rx_ahb => not handled by the grspw driver
939 // housekeeping_packet.hk_lfr_dpu_spw_tx_ahb => not handled by the grspw driver
941 // housekeeping_packet.hk_lfr_dpu_spw_tx_ahb => not handled by the grspw driver
940
942
941 // update the le counter
943 // update the le counter
942 // DPU
944 // DPU
943 increment_hk_counter( new_hk_lfr_le.dpu_spw_parity, old_hk_lfr_le.dpu_spw_parity, &counter );
945 increment_hk_counter( new_hk_lfr_le.dpu_spw_parity, old_hk_lfr_le.dpu_spw_parity, &counter );
944 increment_hk_counter( new_hk_lfr_le.dpu_spw_disconnect,old_hk_lfr_le.dpu_spw_disconnect, &counter );
946 increment_hk_counter( new_hk_lfr_le.dpu_spw_disconnect,old_hk_lfr_le.dpu_spw_disconnect, &counter );
945 increment_hk_counter( new_hk_lfr_le.dpu_spw_escape, old_hk_lfr_le.dpu_spw_escape, &counter );
947 increment_hk_counter( new_hk_lfr_le.dpu_spw_escape, old_hk_lfr_le.dpu_spw_escape, &counter );
946 increment_hk_counter( new_hk_lfr_le.dpu_spw_credit, old_hk_lfr_le.dpu_spw_credit, &counter );
948 increment_hk_counter( new_hk_lfr_le.dpu_spw_credit, old_hk_lfr_le.dpu_spw_credit, &counter );
947 increment_hk_counter( new_hk_lfr_le.dpu_spw_write_sync,old_hk_lfr_le.dpu_spw_write_sync, &counter );
949 increment_hk_counter( new_hk_lfr_le.dpu_spw_write_sync,old_hk_lfr_le.dpu_spw_write_sync, &counter );
948 // TIMECODE
950 // TIMECODE
949 increment_hk_counter( new_hk_lfr_le.timecode_erroneous,old_hk_lfr_le.timecode_erroneous, &counter );
951 increment_hk_counter( new_hk_lfr_le.timecode_erroneous,old_hk_lfr_le.timecode_erroneous, &counter );
950 increment_hk_counter( new_hk_lfr_le.timecode_missing, old_hk_lfr_le.timecode_missing, &counter );
952 increment_hk_counter( new_hk_lfr_le.timecode_missing, old_hk_lfr_le.timecode_missing, &counter );
951 increment_hk_counter( new_hk_lfr_le.timecode_invalid, old_hk_lfr_le.timecode_invalid, &counter );
953 increment_hk_counter( new_hk_lfr_le.timecode_invalid, old_hk_lfr_le.timecode_invalid, &counter );
952 // TIME
954 // TIME
953 increment_hk_counter( new_hk_lfr_le.time_timecode_it, old_hk_lfr_le.time_timecode_it, &counter );
955 increment_hk_counter( new_hk_lfr_le.time_timecode_it, old_hk_lfr_le.time_timecode_it, &counter );
954 increment_hk_counter( new_hk_lfr_le.time_not_synchro, old_hk_lfr_le.time_not_synchro, &counter );
956 increment_hk_counter( new_hk_lfr_le.time_not_synchro, old_hk_lfr_le.time_not_synchro, &counter );
955 increment_hk_counter( new_hk_lfr_le.time_timecode_ctr, old_hk_lfr_le.time_timecode_ctr, &counter );
957 increment_hk_counter( new_hk_lfr_le.time_timecode_ctr, old_hk_lfr_le.time_timecode_ctr, &counter );
956 // AHB
958 // AHB
957 increment_hk_counter( new_hk_lfr_le.ahb_correctable, old_hk_lfr_le.ahb_correctable, &counter );
959 increment_hk_counter( new_hk_lfr_le.ahb_correctable, old_hk_lfr_le.ahb_correctable, &counter );
958
960
959 // DPU
961 // DPU
960 old_hk_lfr_le.dpu_spw_parity = new_hk_lfr_le.dpu_spw_parity;
962 old_hk_lfr_le.dpu_spw_parity = new_hk_lfr_le.dpu_spw_parity;
961 old_hk_lfr_le.dpu_spw_disconnect= new_hk_lfr_le.dpu_spw_disconnect;
963 old_hk_lfr_le.dpu_spw_disconnect= new_hk_lfr_le.dpu_spw_disconnect;
962 old_hk_lfr_le.dpu_spw_escape = new_hk_lfr_le.dpu_spw_escape;
964 old_hk_lfr_le.dpu_spw_escape = new_hk_lfr_le.dpu_spw_escape;
963 old_hk_lfr_le.dpu_spw_credit = new_hk_lfr_le.dpu_spw_credit;
965 old_hk_lfr_le.dpu_spw_credit = new_hk_lfr_le.dpu_spw_credit;
964 old_hk_lfr_le.dpu_spw_write_sync= new_hk_lfr_le.dpu_spw_write_sync;
966 old_hk_lfr_le.dpu_spw_write_sync= new_hk_lfr_le.dpu_spw_write_sync;
965 // TIMECODE
967 // TIMECODE
966 old_hk_lfr_le.timecode_erroneous= new_hk_lfr_le.timecode_erroneous;
968 old_hk_lfr_le.timecode_erroneous= new_hk_lfr_le.timecode_erroneous;
967 old_hk_lfr_le.timecode_missing = new_hk_lfr_le.timecode_missing;
969 old_hk_lfr_le.timecode_missing = new_hk_lfr_le.timecode_missing;
968 old_hk_lfr_le.timecode_invalid = new_hk_lfr_le.timecode_invalid;
970 old_hk_lfr_le.timecode_invalid = new_hk_lfr_le.timecode_invalid;
969 // TIME
971 // TIME
970 old_hk_lfr_le.time_timecode_it = new_hk_lfr_le.time_timecode_it;
972 old_hk_lfr_le.time_timecode_it = new_hk_lfr_le.time_timecode_it;
971 old_hk_lfr_le.time_not_synchro = new_hk_lfr_le.time_not_synchro;
973 old_hk_lfr_le.time_not_synchro = new_hk_lfr_le.time_not_synchro;
972 old_hk_lfr_le.time_timecode_ctr = new_hk_lfr_le.time_timecode_ctr;
974 old_hk_lfr_le.time_timecode_ctr = new_hk_lfr_le.time_timecode_ctr;
973 //AHB
975 //AHB
974 old_hk_lfr_le.ahb_correctable = new_hk_lfr_le.ahb_correctable;
976 old_hk_lfr_le.ahb_correctable = new_hk_lfr_le.ahb_correctable;
975 // housekeeping_packet.hk_lfr_dpu_spw_rx_ahb => not handled by the grspw driver
977 // housekeeping_packet.hk_lfr_dpu_spw_rx_ahb => not handled by the grspw driver
976 // housekeeping_packet.hk_lfr_dpu_spw_tx_ahb => not handled by the grspw driver
978 // housekeeping_packet.hk_lfr_dpu_spw_tx_ahb => not handled by the grspw driver
977
979
978 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
980 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
979 // LE
981 // LE
980 housekeeping_packet.hk_lfr_le_cnt[0] = (unsigned char) ((counter & BYTE0_MASK) >> SHIFT_1_BYTE);
982 housekeeping_packet.hk_lfr_le_cnt[0] = (unsigned char) ((counter & BYTE0_MASK) >> SHIFT_1_BYTE);
981 housekeeping_packet.hk_lfr_le_cnt[1] = (unsigned char) (counter & BYTE1_MASK);
983 housekeeping_packet.hk_lfr_le_cnt[1] = (unsigned char) (counter & BYTE1_MASK);
982 }
984 }
983
985
984 // Medium severity error counters update
986 // Medium severity error counters update
985 void hk_lfr_me_update( void )
987 void hk_lfr_me_update( void )
986 {
988 {
987 static hk_lfr_me_t old_hk_lfr_me = {0};
989 static hk_lfr_me_t old_hk_lfr_me = {0};
988 hk_lfr_me_t new_hk_lfr_me;
990 hk_lfr_me_t new_hk_lfr_me;
989 unsigned int counter;
991 unsigned int counter;
990
992
991 counter = (((unsigned int) housekeeping_packet.hk_lfr_me_cnt[0]) * CONST_256) + housekeeping_packet.hk_lfr_me_cnt[1];
993 counter = (((unsigned int) housekeeping_packet.hk_lfr_me_cnt[0]) * CONST_256) + housekeeping_packet.hk_lfr_me_cnt[1];
992
994
993 // get the current values
995 // get the current values
994 new_hk_lfr_me.dpu_spw_early_eop = housekeeping_packet.hk_lfr_dpu_spw_early_eop;
996 new_hk_lfr_me.dpu_spw_early_eop = housekeeping_packet.hk_lfr_dpu_spw_early_eop;
995 new_hk_lfr_me.dpu_spw_invalid_addr = housekeeping_packet.hk_lfr_dpu_spw_invalid_addr;
997 new_hk_lfr_me.dpu_spw_invalid_addr = housekeeping_packet.hk_lfr_dpu_spw_invalid_addr;
996 new_hk_lfr_me.dpu_spw_eep = housekeeping_packet.hk_lfr_dpu_spw_eep;
998 new_hk_lfr_me.dpu_spw_eep = housekeeping_packet.hk_lfr_dpu_spw_eep;
997 new_hk_lfr_me.dpu_spw_rx_too_big = housekeeping_packet.hk_lfr_dpu_spw_rx_too_big;
999 new_hk_lfr_me.dpu_spw_rx_too_big = housekeeping_packet.hk_lfr_dpu_spw_rx_too_big;
998
1000
999 // update the me counter
1001 // update the me counter
1000 increment_hk_counter( new_hk_lfr_me.dpu_spw_early_eop, old_hk_lfr_me.dpu_spw_early_eop, &counter );
1002 increment_hk_counter( new_hk_lfr_me.dpu_spw_early_eop, old_hk_lfr_me.dpu_spw_early_eop, &counter );
1001 increment_hk_counter( new_hk_lfr_me.dpu_spw_invalid_addr, old_hk_lfr_me.dpu_spw_invalid_addr, &counter );
1003 increment_hk_counter( new_hk_lfr_me.dpu_spw_invalid_addr, old_hk_lfr_me.dpu_spw_invalid_addr, &counter );
1002 increment_hk_counter( new_hk_lfr_me.dpu_spw_eep, old_hk_lfr_me.dpu_spw_eep, &counter );
1004 increment_hk_counter( new_hk_lfr_me.dpu_spw_eep, old_hk_lfr_me.dpu_spw_eep, &counter );
1003 increment_hk_counter( new_hk_lfr_me.dpu_spw_rx_too_big, old_hk_lfr_me.dpu_spw_rx_too_big, &counter );
1005 increment_hk_counter( new_hk_lfr_me.dpu_spw_rx_too_big, old_hk_lfr_me.dpu_spw_rx_too_big, &counter );
1004
1006
1005 // store the counters for the next time
1007 // store the counters for the next time
1006 old_hk_lfr_me.dpu_spw_early_eop = new_hk_lfr_me.dpu_spw_early_eop;
1008 old_hk_lfr_me.dpu_spw_early_eop = new_hk_lfr_me.dpu_spw_early_eop;
1007 old_hk_lfr_me.dpu_spw_invalid_addr = new_hk_lfr_me.dpu_spw_invalid_addr;
1009 old_hk_lfr_me.dpu_spw_invalid_addr = new_hk_lfr_me.dpu_spw_invalid_addr;
1008 old_hk_lfr_me.dpu_spw_eep = new_hk_lfr_me.dpu_spw_eep;
1010 old_hk_lfr_me.dpu_spw_eep = new_hk_lfr_me.dpu_spw_eep;
1009 old_hk_lfr_me.dpu_spw_rx_too_big = new_hk_lfr_me.dpu_spw_rx_too_big;
1011 old_hk_lfr_me.dpu_spw_rx_too_big = new_hk_lfr_me.dpu_spw_rx_too_big;
1010
1012
1011 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
1013 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
1012 // ME
1014 // ME
1013 housekeeping_packet.hk_lfr_me_cnt[0] = (unsigned char) ((counter & BYTE0_MASK) >> SHIFT_1_BYTE);
1015 housekeeping_packet.hk_lfr_me_cnt[0] = (unsigned char) ((counter & BYTE0_MASK) >> SHIFT_1_BYTE);
1014 housekeeping_packet.hk_lfr_me_cnt[1] = (unsigned char) (counter & BYTE1_MASK);
1016 housekeeping_packet.hk_lfr_me_cnt[1] = (unsigned char) (counter & BYTE1_MASK);
1015 }
1017 }
1016
1018
1017 // High severity error counters update
1019 // High severity error counters update
1018 void hk_lfr_le_me_he_update()
1020 void hk_lfr_le_me_he_update()
1019 {
1021 {
1020
1022
1021 unsigned int hk_lfr_he_cnt;
1023 unsigned int hk_lfr_he_cnt;
1022
1024
1023 hk_lfr_he_cnt = (((unsigned int) housekeeping_packet.hk_lfr_he_cnt[0]) * 256) + housekeeping_packet.hk_lfr_he_cnt[1];
1025 hk_lfr_he_cnt = (((unsigned int) housekeeping_packet.hk_lfr_he_cnt[0]) * 256) + housekeeping_packet.hk_lfr_he_cnt[1];
1024
1026
1025 //update the low severity error counter
1027 //update the low severity error counter
1026 hk_lfr_le_update( );
1028 hk_lfr_le_update( );
1027
1029
1028 //update the medium severity error counter
1030 //update the medium severity error counter
1029 hk_lfr_me_update();
1031 hk_lfr_me_update();
1030
1032
1031 //update the high severity error counter
1033 //update the high severity error counter
1032 hk_lfr_he_cnt = 0;
1034 hk_lfr_he_cnt = 0;
1033
1035
1034 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
1036 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
1035 // HE
1037 // HE
1036 housekeeping_packet.hk_lfr_he_cnt[0] = (unsigned char) ((hk_lfr_he_cnt & BYTE0_MASK) >> SHIFT_1_BYTE);
1038 housekeeping_packet.hk_lfr_he_cnt[0] = (unsigned char) ((hk_lfr_he_cnt & BYTE0_MASK) >> SHIFT_1_BYTE);
1037 housekeeping_packet.hk_lfr_he_cnt[1] = (unsigned char) (hk_lfr_he_cnt & BYTE1_MASK);
1039 housekeeping_packet.hk_lfr_he_cnt[1] = (unsigned char) (hk_lfr_he_cnt & BYTE1_MASK);
1038
1040
1039 }
1041 }
1040
1042
1041 void set_hk_lfr_time_not_synchro()
1043 void set_hk_lfr_time_not_synchro()
1042 {
1044 {
1043 static unsigned char synchroLost = 1;
1045 static unsigned char synchroLost = 1;
1044 int synchronizationBit;
1046 int synchronizationBit;
1045
1047
1046 // get the synchronization bit
1048 // get the synchronization bit
1047 synchronizationBit =
1049 synchronizationBit =
1048 (time_management_regs->coarse_time & VAL_LFR_SYNCHRONIZED) >> BIT_SYNCHRONIZATION; // 1000 0000 0000 0000
1050 (time_management_regs->coarse_time & VAL_LFR_SYNCHRONIZED) >> BIT_SYNCHRONIZATION; // 1000 0000 0000 0000
1049
1051
1050 switch (synchronizationBit)
1052 switch (synchronizationBit)
1051 {
1053 {
1052 case 0:
1054 case 0:
1053 if (synchroLost == 1)
1055 if (synchroLost == 1)
1054 {
1056 {
1055 synchroLost = 0;
1057 synchroLost = 0;
1056 }
1058 }
1057 break;
1059 break;
1058 case 1:
1060 case 1:
1059 if (synchroLost == 0 )
1061 if (synchroLost == 0 )
1060 {
1062 {
1061 synchroLost = 1;
1063 synchroLost = 1;
1062 increase_unsigned_char_counter(&housekeeping_packet.hk_lfr_time_not_synchro);
1064 increase_unsigned_char_counter(&housekeeping_packet.hk_lfr_time_not_synchro);
1063 update_hk_lfr_last_er_fields( RID_LE_LFR_TIME, CODE_NOT_SYNCHRO );
1065 update_hk_lfr_last_er_fields( RID_LE_LFR_TIME, CODE_NOT_SYNCHRO );
1064 }
1066 }
1065 break;
1067 break;
1066 default:
1068 default:
1067 PRINTF1("in hk_lfr_time_not_synchro *** unexpected value for synchronizationBit = %d\n", synchronizationBit);
1069 PRINTF1("in hk_lfr_time_not_synchro *** unexpected value for synchronizationBit = %d\n", synchronizationBit);
1068 break;
1070 break;
1069 }
1071 }
1070
1072
1071 }
1073 }
1072
1074
1073 void set_hk_lfr_ahb_correctable() // CRITICITY L
1075 void set_hk_lfr_ahb_correctable() // CRITICITY L
1074 {
1076 {
1075 /** This function builds the error counter hk_lfr_ahb_correctable using the statistics provided
1077 /** This function builds the error counter hk_lfr_ahb_correctable using the statistics provided
1076 * by the Cache Control Register (ASI 2, offset 0) and in the Register Protection Control Register (ASR16) on the
1078 * by the Cache Control Register (ASI 2, offset 0) and in the Register Protection Control Register (ASR16) on the
1077 * detected errors in the cache, in the integer unit and in the floating point unit.
1079 * detected errors in the cache, in the integer unit and in the floating point unit.
1078 *
1080 *
1079 * @param void
1081 * @param void
1080 *
1082 *
1081 * @return void
1083 * @return void
1082 *
1084 *
1083 * All errors are summed to set the value of the hk_lfr_ahb_correctable counter.
1085 * All errors are summed to set the value of the hk_lfr_ahb_correctable counter.
1084 *
1086 *
1085 */
1087 */
1086
1088
1087 unsigned int ahb_correctable;
1089 unsigned int ahb_correctable;
1088 unsigned int instructionErrorCounter;
1090 unsigned int instructionErrorCounter;
1089 unsigned int dataErrorCounter;
1091 unsigned int dataErrorCounter;
1090 unsigned int fprfErrorCounter;
1092 unsigned int fprfErrorCounter;
1091 unsigned int iurfErrorCounter;
1093 unsigned int iurfErrorCounter;
1092
1094
1093 instructionErrorCounter = 0;
1095 instructionErrorCounter = 0;
1094 dataErrorCounter = 0;
1096 dataErrorCounter = 0;
1095 fprfErrorCounter = 0;
1097 fprfErrorCounter = 0;
1096 iurfErrorCounter = 0;
1098 iurfErrorCounter = 0;
1097
1099
1098 CCR_getInstructionAndDataErrorCounters( &instructionErrorCounter, &dataErrorCounter);
1100 CCR_getInstructionAndDataErrorCounters( &instructionErrorCounter, &dataErrorCounter);
1099 ASR16_get_FPRF_IURF_ErrorCounters( &fprfErrorCounter, &iurfErrorCounter);
1101 ASR16_get_FPRF_IURF_ErrorCounters( &fprfErrorCounter, &iurfErrorCounter);
1100
1102
1101 ahb_correctable = instructionErrorCounter
1103 ahb_correctable = instructionErrorCounter
1102 + dataErrorCounter
1104 + dataErrorCounter
1103 + fprfErrorCounter
1105 + fprfErrorCounter
1104 + iurfErrorCounter
1106 + iurfErrorCounter
1105 + housekeeping_packet.hk_lfr_ahb_correctable;
1107 + housekeeping_packet.hk_lfr_ahb_correctable;
1106
1108
1107 housekeeping_packet.hk_lfr_ahb_correctable = (unsigned char) (ahb_correctable & INT8_ALL_F); // [1111 1111]
1109 housekeeping_packet.hk_lfr_ahb_correctable = (unsigned char) (ahb_correctable & INT8_ALL_F); // [1111 1111]
1108
1110
1109 }
1111 }
@@ -1,504 +1,500
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW),
2 -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW),
3 -- This file is a part of the LFR FSW
3 -- This file is a part of the LFR FSW
4 -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS
4 -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS
5 --
5 --
6 -- This program is free software; you can redistribute it and/or modify
6 -- This program is free software; you can redistribute it and/or modify
7 -- it under the terms of the GNU General Public License as published by
7 -- it under the terms of the GNU General Public License as published by
8 -- the Free Software Foundation; either version 2 of the License, or
8 -- the Free Software Foundation; either version 2 of the License, or
9 -- (at your option) any later version.
9 -- (at your option) any later version.
10 --
10 --
11 -- This program is distributed in the hope that it will be useful,
11 -- This program is distributed in the hope that it will be useful,
12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 -- GNU General Public License for more details.
14 -- GNU General Public License for more details.
15 --
15 --
16 -- You should have received a copy of the GNU General Public License
16 -- You should have received a copy of the GNU General Public License
17 -- along with this program; if not, write to the Free Software
17 -- along with this program; if not, write to the Free Software
18 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 -------------------------------------------------------------------------------*/
19 -------------------------------------------------------------------------------*/
20 /*-- Author : Paul Leroy
20 /*-- Author : Paul Leroy
21 -- Contact : Alexis Jeandet
21 -- Contact : Alexis Jeandet
22 -- Mail : alexis.jeandet@lpp.polytechnique.fr
22 -- Mail : alexis.jeandet@lpp.polytechnique.fr
23 ----------------------------------------------------------------------------*/
23 ----------------------------------------------------------------------------*/
24 /** Functions related to TeleCommand acceptance.
24 /** Functions related to TeleCommand acceptance.
25 *
25 *
26 * @file
26 * @file
27 * @author P. LEROY
27 * @author P. LEROY
28 *
28 *
29 * A group of functions to handle TeleCommands parsing.\n
29 * A group of functions to handle TeleCommands parsing.\n
30 *
30 *
31 */
31 */
32
32
33 #include "tc_acceptance.h"
33 #include "tc_acceptance.h"
34 #include <stdio.h>
34 #include <stdio.h>
35
35
36 unsigned int lookUpTableForCRC[CONST_256] = {0};
36 unsigned int lookUpTableForCRC[CONST_256] = {0};
37
37
38 //**********************
38 //**********************
39 // GENERAL USE FUNCTIONS
39 // GENERAL USE FUNCTIONS
40 unsigned int Crc_opt( unsigned char D, unsigned int Chk)
40 unsigned int Crc_opt( unsigned char D, unsigned int Chk)
41 {
41 {
42 /** This function generate the CRC for one byte and returns the value of the new syndrome.
42 /** This function generate the CRC for one byte and returns the value of the new syndrome.
43 *
43 *
44 * @param D is the current byte of data.
44 * @param D is the current byte of data.
45 * @param Chk is the current syndrom value.
45 * @param Chk is the current syndrom value.
46 *
46 *
47 * @return the value of the new syndrome on two bytes.
47 * @return the value of the new syndrome on two bytes.
48 *
48 *
49 */
49 */
50
50
51 return(((Chk << SHIFT_1_BYTE) & BYTE0_MASK)^lookUpTableForCRC [(((Chk >> SHIFT_1_BYTE)^D) & BYTE1_MASK)]);
51 return(((Chk << SHIFT_1_BYTE) & BYTE0_MASK)^lookUpTableForCRC [(((Chk >> SHIFT_1_BYTE)^D) & BYTE1_MASK)]);
52 }
52 }
53
53
54 void initLookUpTableForCRC( void )
54 void initLookUpTableForCRC( void )
55 {
55 {
56 /** This function is used to initiates the look-up table for fast CRC computation.
56 /** This function is used to initiates the look-up table for fast CRC computation.
57 *
57 *
58 * The global table lookUpTableForCRC[256] is initiated.
58 * The global table lookUpTableForCRC[256] is initiated.
59 *
59 *
60 */
60 */
61
61
62 unsigned int i;
62 unsigned int i;
63 unsigned int tmp;
63 unsigned int tmp;
64
64
65 for (i=0; i<CONST_256; i++)
65 for (i=0; i<CONST_256; i++)
66 {
66 {
67 tmp = 0;
67 tmp = 0;
68 if((i & BIT_0) != 0) {
68 if((i & BIT_0) != 0) {
69 tmp = tmp ^ CONST_CRC_0;
69 tmp = tmp ^ CONST_CRC_0;
70 }
70 }
71 if((i & BIT_1) != 0) {
71 if((i & BIT_1) != 0) {
72 tmp = tmp ^ CONST_CRC_1;
72 tmp = tmp ^ CONST_CRC_1;
73 }
73 }
74 if((i & BIT_2) != 0) {
74 if((i & BIT_2) != 0) {
75 tmp = tmp ^ CONST_CRC_2;
75 tmp = tmp ^ CONST_CRC_2;
76 }
76 }
77 if((i & BIT_3) != 0) {
77 if((i & BIT_3) != 0) {
78 tmp = tmp ^ CONST_CRC_3;
78 tmp = tmp ^ CONST_CRC_3;
79 }
79 }
80 if((i & BIT_4) != 0) {
80 if((i & BIT_4) != 0) {
81 tmp = tmp ^ CONST_CRC_4;
81 tmp = tmp ^ CONST_CRC_4;
82 }
82 }
83 if((i & BIT_5) != 0) {
83 if((i & BIT_5) != 0) {
84 tmp = tmp ^ CONST_CRC_5;
84 tmp = tmp ^ CONST_CRC_5;
85 }
85 }
86 if((i & BIT_6) != 0) {
86 if((i & BIT_6) != 0) {
87 tmp = tmp ^ CONST_CRC_6;
87 tmp = tmp ^ CONST_CRC_6;
88 }
88 }
89 if((i & BIT_7) != 0) {
89 if((i & BIT_7) != 0) {
90 tmp = tmp ^ CONST_CRC_7;
90 tmp = tmp ^ CONST_CRC_7;
91 }
91 }
92 lookUpTableForCRC[i] = tmp;
92 lookUpTableForCRC[i] = tmp;
93 }
93 }
94 }
94 }
95
95
96 void GetCRCAsTwoBytes(unsigned char* data, unsigned char* crcAsTwoBytes, unsigned int sizeOfData)
96 void GetCRCAsTwoBytes(unsigned char* data, unsigned char* crcAsTwoBytes, unsigned int sizeOfData)
97 {
97 {
98 /** This function calculates a two bytes Cyclic Redundancy Code.
98 /** This function calculates a two bytes Cyclic Redundancy Code.
99 *
99 *
100 * @param data points to a buffer containing the data on which to compute the CRC.
100 * @param data points to a buffer containing the data on which to compute the CRC.
101 * @param crcAsTwoBytes points points to a two bytes buffer in which the CRC is stored.
101 * @param crcAsTwoBytes points points to a two bytes buffer in which the CRC is stored.
102 * @param sizeOfData is the number of bytes of *data* used to compute the CRC.
102 * @param sizeOfData is the number of bytes of *data* used to compute the CRC.
103 *
103 *
104 * The specification of the Cyclic Redundancy Code is described in the following document: ECSS-E-70-41-A.
104 * The specification of the Cyclic Redundancy Code is described in the following document: ECSS-E-70-41-A.
105 *
105 *
106 */
106 */
107
107
108 unsigned int Chk;
108 unsigned int Chk;
109 int j;
109 int j;
110 Chk = CRC_RESET; // reset the syndrom to all ones
110 Chk = CRC_RESET; // reset the syndrom to all ones
111 for (j=0; j<sizeOfData; j++) {
111 for (j=0; j<sizeOfData; j++) {
112 Chk = Crc_opt(data[j], Chk);
112 Chk = Crc_opt(data[j], Chk);
113 }
113 }
114 crcAsTwoBytes[0] = (unsigned char) (Chk >> SHIFT_1_BYTE);
114 crcAsTwoBytes[0] = (unsigned char) (Chk >> SHIFT_1_BYTE);
115 crcAsTwoBytes[1] = (unsigned char) (Chk & BYTE1_MASK);
115 crcAsTwoBytes[1] = (unsigned char) (Chk & BYTE1_MASK);
116 }
116 }
117
117
118 //*********************
118 //*********************
119 // ACCEPTANCE FUNCTIONS
119 // ACCEPTANCE FUNCTIONS
120 int tc_parser(ccsdsTelecommandPacket_t * TCPacket, unsigned int estimatedPacketLength, unsigned char *computed_CRC)
120 int tc_parser(ccsdsTelecommandPacket_t * TCPacket, unsigned int estimatedPacketLength, unsigned char *computed_CRC)
121 {
121 {
122 /** This function parses TeleCommands.
122 /** This function parses TeleCommands.
123 *
123 *
124 * @param TC points to the TeleCommand that will be parsed.
124 * @param TC points to the TeleCommand that will be parsed.
125 * @param estimatedPacketLength is the PACKET_LENGTH field calculated from the effective length of the received packet.
125 * @param estimatedPacketLength is the PACKET_LENGTH field calculated from the effective length of the received packet.
126 *
126 *
127 * @return Status code of the parsing.
127 * @return Status code of the parsing.
128 *
128 *
129 * The parsing checks:
129 * The parsing checks:
130 * - process id
130 * - process id
131 * - category
131 * - category
132 * - length: a global check is performed and a per subtype check also
132 * - length: a global check is performed and a per subtype check also
133 * - type
133 * - type
134 * - subtype
134 * - subtype
135 * - crc
135 * - crc
136 *
136 *
137 */
137 */
138
138
139 int status;
139 int status;
140 int status_crc;
140 int status_crc;
141 unsigned char pid;
141 unsigned char pid;
142 unsigned char category;
142 unsigned char category;
143 unsigned int packetLength;
143 unsigned int packetLength;
144 unsigned char packetType;
144 unsigned char packetType;
145 unsigned char packetSubtype;
145 unsigned char packetSubtype;
146 unsigned char sid;
146 unsigned char sid;
147
147
148 status = CCSDS_TM_VALID;
148 status = CCSDS_TM_VALID;
149
149
150 // APID check *** APID on 2 bytes
150 // APID check *** APID on 2 bytes
151 pid = ((TCPacket->packetID[0] & BITS_PID_0) << SHIFT_4_BITS)
151 pid = ((TCPacket->packetID[0] & BITS_PID_0) << SHIFT_4_BITS)
152 + ( (TCPacket->packetID[1] >> SHIFT_4_BITS) & BITS_PID_1 ); // PID = 11 *** 7 bits xxxxx210 7654xxxx
152 + ( (TCPacket->packetID[1] >> SHIFT_4_BITS) & BITS_PID_1 ); // PID = 11 *** 7 bits xxxxx210 7654xxxx
153 category = (TCPacket->packetID[1] & BITS_CAT); // PACKET_CATEGORY = 12 *** 4 bits xxxxxxxx xxxx3210
153 category = (TCPacket->packetID[1] & BITS_CAT); // PACKET_CATEGORY = 12 *** 4 bits xxxxxxxx xxxx3210
154 packetLength = (TCPacket->packetLength[0] * CONST_256) + TCPacket->packetLength[1];
154 packetLength = (TCPacket->packetLength[0] * CONST_256) + TCPacket->packetLength[1];
155 packetType = TCPacket->serviceType;
155 packetType = TCPacket->serviceType;
156 packetSubtype = TCPacket->serviceSubType;
156 packetSubtype = TCPacket->serviceSubType;
157 sid = TCPacket->sourceID;
157 sid = TCPacket->sourceID;
158
158
159 if ( pid != CCSDS_PROCESS_ID ) // CHECK THE PROCESS ID
159 if ( pid != CCSDS_PROCESS_ID ) // CHECK THE PROCESS ID
160 {
160 {
161 status = ILLEGAL_APID;
161 status = ILLEGAL_APID;
162 }
162 }
163 if (status == CCSDS_TM_VALID) // CHECK THE CATEGORY
163 if (status == CCSDS_TM_VALID) // CHECK THE CATEGORY
164 {
164 {
165 if ( category != CCSDS_PACKET_CATEGORY )
165 if ( category != CCSDS_PACKET_CATEGORY )
166 {
166 {
167 status = ILLEGAL_APID;
167 status = ILLEGAL_APID;
168 }
168 }
169 }
169 }
170 if (status == CCSDS_TM_VALID) // CHECK THE PACKET_LENGTH FIELD AND THE ESTIMATED PACKET_LENGTH COMPLIANCE
170 if (status == CCSDS_TM_VALID) // CHECK THE PACKET_LENGTH FIELD AND THE ESTIMATED PACKET_LENGTH COMPLIANCE
171 {
171 {
172 if (packetLength != estimatedPacketLength ) {
172 if (packetLength != estimatedPacketLength ) {
173 status = WRONG_LEN_PKT;
173 status = WRONG_LEN_PKT;
174 }
174 }
175 }
175 }
176 if (status == CCSDS_TM_VALID) // CHECK THAT THE PACKET DOES NOT EXCEED THE MAX SIZE
176 if (status == CCSDS_TM_VALID) // CHECK THAT THE PACKET DOES NOT EXCEED THE MAX SIZE
177 {
177 {
178 if ( packetLength > CCSDS_TC_PKT_MAX_SIZE ) {
178 if ( packetLength > CCSDS_TC_PKT_MAX_SIZE ) {
179 status = WRONG_LEN_PKT;
179 status = WRONG_LEN_PKT;
180 }
180 }
181 }
181 }
182 if (status == CCSDS_TM_VALID) // CHECK THE TYPE
182 if (status == CCSDS_TM_VALID) // CHECK THE TYPE
183 {
183 {
184 status = tc_check_type( packetType );
184 status = tc_check_type( packetType );
185 }
185 }
186 if (status == CCSDS_TM_VALID) // CHECK THE SUBTYPE
186 if (status == CCSDS_TM_VALID) // CHECK THE SUBTYPE
187 {
187 {
188 status = tc_check_type_subtype( packetType, packetSubtype );
188 status = tc_check_type_subtype( packetType, packetSubtype );
189 }
189 }
190 if (status == CCSDS_TM_VALID) // CHECK THE SID
190 if (status == CCSDS_TM_VALID) // CHECK THE SID
191 {
191 {
192 status = tc_check_sid( sid );
192 status = tc_check_sid( sid );
193 }
193 }
194 if (status == CCSDS_TM_VALID) // CHECK THE SUBTYPE AND LENGTH COMPLIANCE
194 if (status == CCSDS_TM_VALID) // CHECK THE SUBTYPE AND LENGTH COMPLIANCE
195 {
195 {
196 status = tc_check_length( packetSubtype, packetLength );
196 status = tc_check_length( packetSubtype, packetLength );
197 }
197 }
198 status_crc = tc_check_crc( TCPacket, estimatedPacketLength, computed_CRC );
198 status_crc = tc_check_crc( TCPacket, estimatedPacketLength, computed_CRC );
199 if (status == CCSDS_TM_VALID ) // CHECK CRC
199 if (status == CCSDS_TM_VALID ) // CHECK CRC
200 {
200 {
201 status = status_crc;
201 status = status_crc;
202 }
202 }
203
203
204 return status;
204 return status;
205 }
205 }
206
206
207 int tc_check_type( unsigned char packetType )
207 int tc_check_type( unsigned char packetType )
208 {
208 {
209 /** This function checks that the type of a TeleCommand is valid.
209 /** This function checks that the type of a TeleCommand is valid.
210 *
210 *
211 * @param packetType is the type to check.
211 * @param packetType is the type to check.
212 *
212 *
213 * @return Status code CCSDS_TM_VALID or ILL_TYPE.
213 * @return Status code CCSDS_TM_VALID or ILL_TYPE.
214 *
214 *
215 */
215 */
216
216
217 int status;
217 int status;
218
218
219 status = ILL_TYPE;
219 status = ILL_TYPE;
220
220
221 if ( (packetType == TC_TYPE_GEN) || (packetType == TC_TYPE_TIME))
221 if ( (packetType == TC_TYPE_GEN) || (packetType == TC_TYPE_TIME))
222 {
222 {
223 status = CCSDS_TM_VALID;
223 status = CCSDS_TM_VALID;
224 }
224 }
225 else
226 {
227 status = ILL_TYPE;
228 }
229
225
230 return status;
226 return status;
231 }
227 }
232
228
233 int tc_check_type_subtype( unsigned char packetType, unsigned char packetSubType )
229 int tc_check_type_subtype( unsigned char packetType, unsigned char packetSubType )
234 {
230 {
235 /** This function checks that the subtype of a TeleCommand is valid and coherent with the type.
231 /** This function checks that the subtype of a TeleCommand is valid and coherent with the type.
236 *
232 *
237 * @param packetType is the type of the TC.
233 * @param packetType is the type of the TC.
238 * @param packetSubType is the subtype to check.
234 * @param packetSubType is the subtype to check.
239 *
235 *
240 * @return Status code CCSDS_TM_VALID or ILL_SUBTYPE.
236 * @return Status code CCSDS_TM_VALID or ILL_SUBTYPE.
241 *
237 *
242 */
238 */
243
239
244 int status;
240 int status;
245
241
246 switch(packetType)
242 switch(packetType)
247 {
243 {
248 case TC_TYPE_GEN:
244 case TC_TYPE_GEN:
249 if ( (packetSubType == TC_SUBTYPE_RESET)
245 if ( (packetSubType == TC_SUBTYPE_RESET)
250 || (packetSubType == TC_SUBTYPE_LOAD_COMM)
246 || (packetSubType == TC_SUBTYPE_LOAD_COMM)
251 || (packetSubType == TC_SUBTYPE_LOAD_NORM) || (packetSubType == TC_SUBTYPE_LOAD_BURST)
247 || (packetSubType == TC_SUBTYPE_LOAD_NORM) || (packetSubType == TC_SUBTYPE_LOAD_BURST)
252 || (packetSubType == TC_SUBTYPE_LOAD_SBM1) || (packetSubType == TC_SUBTYPE_LOAD_SBM2)
248 || (packetSubType == TC_SUBTYPE_LOAD_SBM1) || (packetSubType == TC_SUBTYPE_LOAD_SBM2)
253 || (packetSubType == TC_SUBTYPE_DUMP)
249 || (packetSubType == TC_SUBTYPE_DUMP)
254 || (packetSubType == TC_SUBTYPE_ENTER)
250 || (packetSubType == TC_SUBTYPE_ENTER)
255 || (packetSubType == TC_SUBTYPE_UPDT_INFO)
251 || (packetSubType == TC_SUBTYPE_UPDT_INFO)
256 || (packetSubType == TC_SUBTYPE_EN_CAL) || (packetSubType == TC_SUBTYPE_DIS_CAL)
252 || (packetSubType == TC_SUBTYPE_EN_CAL) || (packetSubType == TC_SUBTYPE_DIS_CAL)
257 || (packetSubType == TC_SUBTYPE_LOAD_K) || (packetSubType == TC_SUBTYPE_DUMP_K)
253 || (packetSubType == TC_SUBTYPE_LOAD_K) || (packetSubType == TC_SUBTYPE_DUMP_K)
258 || (packetSubType == TC_SUBTYPE_LOAD_FBINS)
254 || (packetSubType == TC_SUBTYPE_LOAD_FBINS)
259 || (packetSubType == TC_SUBTYPE_LOAD_FILTER_PAR))
255 || (packetSubType == TC_SUBTYPE_LOAD_FILTER_PAR))
260 {
256 {
261 status = CCSDS_TM_VALID;
257 status = CCSDS_TM_VALID;
262 }
258 }
263 else
259 else
264 {
260 {
265 status = ILL_SUBTYPE;
261 status = ILL_SUBTYPE;
266 }
262 }
267 break;
263 break;
268
264
269 case TC_TYPE_TIME:
265 case TC_TYPE_TIME:
270 if (packetSubType == TC_SUBTYPE_UPDT_TIME)
266 if (packetSubType == TC_SUBTYPE_UPDT_TIME)
271 {
267 {
272 status = CCSDS_TM_VALID;
268 status = CCSDS_TM_VALID;
273 }
269 }
274 else
270 else
275 {
271 {
276 status = ILL_SUBTYPE;
272 status = ILL_SUBTYPE;
277 }
273 }
278 break;
274 break;
279
275
280 default:
276 default:
281 status = ILL_SUBTYPE;
277 status = ILL_SUBTYPE;
282 break;
278 break;
283 }
279 }
284
280
285 return status;
281 return status;
286 }
282 }
287
283
288 int tc_check_sid( unsigned char sid )
284 int tc_check_sid( unsigned char sid )
289 {
285 {
290 /** This function checks that the sid of a TeleCommand is valid.
286 /** This function checks that the sid of a TeleCommand is valid.
291 *
287 *
292 * @param sid is the sid to check.
288 * @param sid is the sid to check.
293 *
289 *
294 * @return Status code CCSDS_TM_VALID or CORRUPTED.
290 * @return Status code CCSDS_TM_VALID or CORRUPTED.
295 *
291 *
296 */
292 */
297
293
298 int status;
294 int status;
299
295
300 status = WRONG_SRC_ID;
296 status = WRONG_SRC_ID;
301
297
302 if ( (sid == SID_TC_MISSION_TIMELINE) || (sid == SID_TC_TC_SEQUENCES) || (sid == SID_TC_RECOVERY_ACTION_CMD)
298 if ( (sid == SID_TC_MISSION_TIMELINE) || (sid == SID_TC_TC_SEQUENCES) || (sid == SID_TC_RECOVERY_ACTION_CMD)
303 || (sid == SID_TC_BACKUP_MISSION_TIMELINE)
299 || (sid == SID_TC_BACKUP_MISSION_TIMELINE)
304 || (sid == SID_TC_DIRECT_CMD) || (sid == SID_TC_SPARE_GRD_SRC1) || (sid == SID_TC_SPARE_GRD_SRC2)
300 || (sid == SID_TC_DIRECT_CMD) || (sid == SID_TC_SPARE_GRD_SRC1) || (sid == SID_TC_SPARE_GRD_SRC2)
305 || (sid == SID_TC_OBCP) || (sid == SID_TC_SYSTEM_CONTROL) || (sid == SID_TC_AOCS)
301 || (sid == SID_TC_OBCP) || (sid == SID_TC_SYSTEM_CONTROL) || (sid == SID_TC_AOCS)
306 || (sid == SID_TC_RPW_INTERNAL))
302 || (sid == SID_TC_RPW_INTERNAL))
307 {
303 {
308 status = CCSDS_TM_VALID;
304 status = CCSDS_TM_VALID;
309 }
305 }
310 else
306 else
311 {
307 {
312 status = WRONG_SRC_ID;
308 status = WRONG_SRC_ID;
313 }
309 }
314
310
315 return status;
311 return status;
316 }
312 }
317
313
318 int tc_check_length( unsigned char packetSubType, unsigned int length )
314 int tc_check_length( unsigned char packetSubType, unsigned int length )
319 {
315 {
320 /** This function checks that the subtype and the length are compliant.
316 /** This function checks that the subtype and the length are compliant.
321 *
317 *
322 * @param packetSubType is the subtype to check.
318 * @param packetSubType is the subtype to check.
323 * @param length is the length to check.
319 * @param length is the length to check.
324 *
320 *
325 * @return Status code CCSDS_TM_VALID or ILL_TYPE.
321 * @return Status code CCSDS_TM_VALID or ILL_TYPE.
326 *
322 *
327 */
323 */
328
324
329 int status;
325 int status;
330
326
331 status = LFR_SUCCESSFUL;
327 status = LFR_SUCCESSFUL;
332
328
333 switch(packetSubType)
329 switch(packetSubType)
334 {
330 {
335 case TC_SUBTYPE_RESET:
331 case TC_SUBTYPE_RESET:
336 if (length!=(TC_LEN_RESET-CCSDS_TC_TM_PACKET_OFFSET)) {
332 if (length!=(TC_LEN_RESET-CCSDS_TC_TM_PACKET_OFFSET)) {
337 status = WRONG_LEN_PKT;
333 status = WRONG_LEN_PKT;
338 }
334 }
339 else {
335 else {
340 status = CCSDS_TM_VALID;
336 status = CCSDS_TM_VALID;
341 }
337 }
342 break;
338 break;
343 case TC_SUBTYPE_LOAD_COMM:
339 case TC_SUBTYPE_LOAD_COMM:
344 if (length!=(TC_LEN_LOAD_COMM-CCSDS_TC_TM_PACKET_OFFSET)) {
340 if (length!=(TC_LEN_LOAD_COMM-CCSDS_TC_TM_PACKET_OFFSET)) {
345 status = WRONG_LEN_PKT;
341 status = WRONG_LEN_PKT;
346 }
342 }
347 else {
343 else {
348 status = CCSDS_TM_VALID;
344 status = CCSDS_TM_VALID;
349 }
345 }
350 break;
346 break;
351 case TC_SUBTYPE_LOAD_NORM:
347 case TC_SUBTYPE_LOAD_NORM:
352 if (length!=(TC_LEN_LOAD_NORM-CCSDS_TC_TM_PACKET_OFFSET)) {
348 if (length!=(TC_LEN_LOAD_NORM-CCSDS_TC_TM_PACKET_OFFSET)) {
353 status = WRONG_LEN_PKT;
349 status = WRONG_LEN_PKT;
354 }
350 }
355 else {
351 else {
356 status = CCSDS_TM_VALID;
352 status = CCSDS_TM_VALID;
357 }
353 }
358 break;
354 break;
359 case TC_SUBTYPE_LOAD_BURST:
355 case TC_SUBTYPE_LOAD_BURST:
360 if (length!=(TC_LEN_LOAD_BURST-CCSDS_TC_TM_PACKET_OFFSET)) {
356 if (length!=(TC_LEN_LOAD_BURST-CCSDS_TC_TM_PACKET_OFFSET)) {
361 status = WRONG_LEN_PKT;
357 status = WRONG_LEN_PKT;
362 }
358 }
363 else {
359 else {
364 status = CCSDS_TM_VALID;
360 status = CCSDS_TM_VALID;
365 }
361 }
366 break;
362 break;
367 case TC_SUBTYPE_LOAD_SBM1:
363 case TC_SUBTYPE_LOAD_SBM1:
368 if (length!=(TC_LEN_LOAD_SBM1-CCSDS_TC_TM_PACKET_OFFSET)) {
364 if (length!=(TC_LEN_LOAD_SBM1-CCSDS_TC_TM_PACKET_OFFSET)) {
369 status = WRONG_LEN_PKT;
365 status = WRONG_LEN_PKT;
370 }
366 }
371 else {
367 else {
372 status = CCSDS_TM_VALID;
368 status = CCSDS_TM_VALID;
373 }
369 }
374 break;
370 break;
375 case TC_SUBTYPE_LOAD_SBM2:
371 case TC_SUBTYPE_LOAD_SBM2:
376 if (length!=(TC_LEN_LOAD_SBM2-CCSDS_TC_TM_PACKET_OFFSET)) {
372 if (length!=(TC_LEN_LOAD_SBM2-CCSDS_TC_TM_PACKET_OFFSET)) {
377 status = WRONG_LEN_PKT;
373 status = WRONG_LEN_PKT;
378 }
374 }
379 else {
375 else {
380 status = CCSDS_TM_VALID;
376 status = CCSDS_TM_VALID;
381 }
377 }
382 break;
378 break;
383 case TC_SUBTYPE_DUMP:
379 case TC_SUBTYPE_DUMP:
384 if (length!=(TC_LEN_DUMP-CCSDS_TC_TM_PACKET_OFFSET)) {
380 if (length!=(TC_LEN_DUMP-CCSDS_TC_TM_PACKET_OFFSET)) {
385 status = WRONG_LEN_PKT;
381 status = WRONG_LEN_PKT;
386 }
382 }
387 else {
383 else {
388 status = CCSDS_TM_VALID;
384 status = CCSDS_TM_VALID;
389 }
385 }
390 break;
386 break;
391 case TC_SUBTYPE_ENTER:
387 case TC_SUBTYPE_ENTER:
392 if (length!=(TC_LEN_ENTER-CCSDS_TC_TM_PACKET_OFFSET)) {
388 if (length!=(TC_LEN_ENTER-CCSDS_TC_TM_PACKET_OFFSET)) {
393 status = WRONG_LEN_PKT;
389 status = WRONG_LEN_PKT;
394 }
390 }
395 else {
391 else {
396 status = CCSDS_TM_VALID;
392 status = CCSDS_TM_VALID;
397 }
393 }
398 break;
394 break;
399 case TC_SUBTYPE_UPDT_INFO:
395 case TC_SUBTYPE_UPDT_INFO:
400 if (length!=(TC_LEN_UPDT_INFO-CCSDS_TC_TM_PACKET_OFFSET)) {
396 if (length!=(TC_LEN_UPDT_INFO-CCSDS_TC_TM_PACKET_OFFSET)) {
401 status = WRONG_LEN_PKT;
397 status = WRONG_LEN_PKT;
402 }
398 }
403 else {
399 else {
404 status = CCSDS_TM_VALID;
400 status = CCSDS_TM_VALID;
405 }
401 }
406 break;
402 break;
407 case TC_SUBTYPE_EN_CAL:
403 case TC_SUBTYPE_EN_CAL:
408 if (length!=(TC_LEN_EN_CAL-CCSDS_TC_TM_PACKET_OFFSET)) {
404 if (length!=(TC_LEN_EN_CAL-CCSDS_TC_TM_PACKET_OFFSET)) {
409 status = WRONG_LEN_PKT;
405 status = WRONG_LEN_PKT;
410 }
406 }
411 else {
407 else {
412 status = CCSDS_TM_VALID;
408 status = CCSDS_TM_VALID;
413 }
409 }
414 break;
410 break;
415 case TC_SUBTYPE_DIS_CAL:
411 case TC_SUBTYPE_DIS_CAL:
416 if (length!=(TC_LEN_DIS_CAL-CCSDS_TC_TM_PACKET_OFFSET)) {
412 if (length!=(TC_LEN_DIS_CAL-CCSDS_TC_TM_PACKET_OFFSET)) {
417 status = WRONG_LEN_PKT;
413 status = WRONG_LEN_PKT;
418 }
414 }
419 else {
415 else {
420 status = CCSDS_TM_VALID;
416 status = CCSDS_TM_VALID;
421 }
417 }
422 break;
418 break;
423 case TC_SUBTYPE_LOAD_K:
419 case TC_SUBTYPE_LOAD_K:
424 if (length!=(TC_LEN_LOAD_K-CCSDS_TC_TM_PACKET_OFFSET)) {
420 if (length!=(TC_LEN_LOAD_K-CCSDS_TC_TM_PACKET_OFFSET)) {
425 status = WRONG_LEN_PKT;
421 status = WRONG_LEN_PKT;
426 }
422 }
427 else {
423 else {
428 status = CCSDS_TM_VALID;
424 status = CCSDS_TM_VALID;
429 }
425 }
430 break;
426 break;
431 case TC_SUBTYPE_DUMP_K:
427 case TC_SUBTYPE_DUMP_K:
432 if (length!=(TC_LEN_DUMP_K-CCSDS_TC_TM_PACKET_OFFSET)) {
428 if (length!=(TC_LEN_DUMP_K-CCSDS_TC_TM_PACKET_OFFSET)) {
433 status = WRONG_LEN_PKT;
429 status = WRONG_LEN_PKT;
434 }
430 }
435 else {
431 else {
436 status = CCSDS_TM_VALID;
432 status = CCSDS_TM_VALID;
437 }
433 }
438 break;
434 break;
439 case TC_SUBTYPE_LOAD_FBINS:
435 case TC_SUBTYPE_LOAD_FBINS:
440 if (length!=(TC_LEN_LOAD_FBINS-CCSDS_TC_TM_PACKET_OFFSET)) {
436 if (length!=(TC_LEN_LOAD_FBINS-CCSDS_TC_TM_PACKET_OFFSET)) {
441 status = WRONG_LEN_PKT;
437 status = WRONG_LEN_PKT;
442 }
438 }
443 else {
439 else {
444 status = CCSDS_TM_VALID;
440 status = CCSDS_TM_VALID;
445 }
441 }
446 break;
442 break;
447 case TC_SUBTYPE_LOAD_FILTER_PAR:
443 case TC_SUBTYPE_LOAD_FILTER_PAR:
448 if (length!=(TC_LEN_LOAD_FILTER_PAR-CCSDS_TC_TM_PACKET_OFFSET)) {
444 if (length!=(TC_LEN_LOAD_FILTER_PAR-CCSDS_TC_TM_PACKET_OFFSET)) {
449 status = WRONG_LEN_PKT;
445 status = WRONG_LEN_PKT;
450 }
446 }
451 else {
447 else {
452 status = CCSDS_TM_VALID;
448 status = CCSDS_TM_VALID;
453 }
449 }
454 break;
450 break;
455 case TC_SUBTYPE_UPDT_TIME:
451 case TC_SUBTYPE_UPDT_TIME:
456 if (length!=(TC_LEN_UPDT_TIME-CCSDS_TC_TM_PACKET_OFFSET)) {
452 if (length!=(TC_LEN_UPDT_TIME-CCSDS_TC_TM_PACKET_OFFSET)) {
457 status = WRONG_LEN_PKT;
453 status = WRONG_LEN_PKT;
458 }
454 }
459 else {
455 else {
460 status = CCSDS_TM_VALID;
456 status = CCSDS_TM_VALID;
461 }
457 }
462 break;
458 break;
463 default: // if the subtype is not a legal value, return ILL_SUBTYPE
459 default: // if the subtype is not a legal value, return ILL_SUBTYPE
464 status = ILL_SUBTYPE;
460 status = ILL_SUBTYPE;
465 break ;
461 break ;
466 }
462 }
467
463
468 return status;
464 return status;
469 }
465 }
470
466
471 int tc_check_crc( ccsdsTelecommandPacket_t * TCPacket, unsigned int length, unsigned char *computed_CRC )
467 int tc_check_crc( ccsdsTelecommandPacket_t * TCPacket, unsigned int length, unsigned char *computed_CRC )
472 {
468 {
473 /** This function checks the CRC validity of the corresponding TeleCommand packet.
469 /** This function checks the CRC validity of the corresponding TeleCommand packet.
474 *
470 *
475 * @param TCPacket points to the TeleCommand packet to check.
471 * @param TCPacket points to the TeleCommand packet to check.
476 * @param length is the length of the TC packet.
472 * @param length is the length of the TC packet.
477 *
473 *
478 * @return Status code CCSDS_TM_VALID or INCOR_CHECKSUM.
474 * @return Status code CCSDS_TM_VALID or INCOR_CHECKSUM.
479 *
475 *
480 */
476 */
481
477
482 int status;
478 int status;
483 unsigned char * CCSDSContent;
479 unsigned char * CCSDSContent;
484
480
485 status = INCOR_CHECKSUM;
481 status = INCOR_CHECKSUM;
486
482
487 CCSDSContent = (unsigned char*) TCPacket->packetID;
483 CCSDSContent = (unsigned char*) TCPacket->packetID;
488 GetCRCAsTwoBytes(CCSDSContent, computed_CRC, length + CCSDS_TC_TM_PACKET_OFFSET - BYTES_PER_CRC); // 2 CRC bytes removed from the calculation of the CRC
484 GetCRCAsTwoBytes(CCSDSContent, computed_CRC, length + CCSDS_TC_TM_PACKET_OFFSET - BYTES_PER_CRC); // 2 CRC bytes removed from the calculation of the CRC
489
485
490 if (computed_CRC[0] != CCSDSContent[length + CCSDS_TC_TM_PACKET_OFFSET - BYTES_PER_CRC]) {
486 if (computed_CRC[0] != CCSDSContent[length + CCSDS_TC_TM_PACKET_OFFSET - BYTES_PER_CRC]) {
491 status = INCOR_CHECKSUM;
487 status = INCOR_CHECKSUM;
492 }
488 }
493 else if (computed_CRC[1] != CCSDSContent[length + CCSDS_TC_TM_PACKET_OFFSET -1]) {
489 else if (computed_CRC[1] != CCSDSContent[length + CCSDS_TC_TM_PACKET_OFFSET -1]) {
494 status = INCOR_CHECKSUM;
490 status = INCOR_CHECKSUM;
495 }
491 }
496 else {
492 else {
497 status = CCSDS_TM_VALID;
493 status = CCSDS_TM_VALID;
498 }
494 }
499
495
500 return status;
496 return status;
501 }
497 }
502
498
503
499
504
500
@@ -1,1702 +1,1692
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW),
2 -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW),
3 -- This file is a part of the LFR FSW
3 -- This file is a part of the LFR FSW
4 -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS
4 -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS
5 --
5 --
6 -- This program is free software; you can redistribute it and/or modify
6 -- This program is free software; you can redistribute it and/or modify
7 -- it under the terms of the GNU General Public License as published by
7 -- it under the terms of the GNU General Public License as published by
8 -- the Free Software Foundation; either version 2 of the License, or
8 -- the Free Software Foundation; either version 2 of the License, or
9 -- (at your option) any later version.
9 -- (at your option) any later version.
10 --
10 --
11 -- This program is distributed in the hope that it will be useful,
11 -- This program is distributed in the hope that it will be useful,
12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 -- GNU General Public License for more details.
14 -- GNU General Public License for more details.
15 --
15 --
16 -- You should have received a copy of the GNU General Public License
16 -- You should have received a copy of the GNU General Public License
17 -- along with this program; if not, write to the Free Software
17 -- along with this program; if not, write to the Free Software
18 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 -------------------------------------------------------------------------------*/
19 -------------------------------------------------------------------------------*/
20 /*-- Author : Paul Leroy
20 /*-- Author : Paul Leroy
21 -- Contact : Alexis Jeandet
21 -- Contact : Alexis Jeandet
22 -- Mail : alexis.jeandet@lpp.polytechnique.fr
22 -- Mail : alexis.jeandet@lpp.polytechnique.fr
23 ----------------------------------------------------------------------------*/
23 ----------------------------------------------------------------------------*/
24 /** Functions and tasks related to TeleCommand handling.
24 /** Functions and tasks related to TeleCommand handling.
25 *
25 *
26 * @file
26 * @file
27 * @author P. LEROY
27 * @author P. LEROY
28 *
28 *
29 * A group of functions to handle TeleCommands:\n
29 * A group of functions to handle TeleCommands:\n
30 * action launching\n
30 * action launching\n
31 * TC parsing\n
31 * TC parsing\n
32 * ...
32 * ...
33 *
33 *
34 */
34 */
35
35
36 #include "tc_handler.h"
36 #include "tc_handler.h"
37 #include "math.h"
37 #include "math.h"
38
38
39 //***********
39 //***********
40 // RTEMS TASK
40 // RTEMS TASK
41
41
42 rtems_task actn_task( rtems_task_argument unused )
42 rtems_task actn_task( rtems_task_argument unused )
43 {
43 {
44 /** This RTEMS task is responsible for launching actions upton the reception of valid TeleCommands.
44 /** This RTEMS task is responsible for launching actions upton the reception of valid TeleCommands.
45 *
45 *
46 * @param unused is the starting argument of the RTEMS task
46 * @param unused is the starting argument of the RTEMS task
47 *
47 *
48 * The ACTN task waits for data coming from an RTEMS msesage queue. When data arrives, it launches specific actions depending
48 * The ACTN task waits for data coming from an RTEMS msesage queue. When data arrives, it launches specific actions depending
49 * on the incoming TeleCommand.
49 * on the incoming TeleCommand.
50 *
50 *
51 */
51 */
52
52
53 int result;
53 int result;
54 rtems_status_code status; // RTEMS status code
54 rtems_status_code status; // RTEMS status code
55 ccsdsTelecommandPacket_t __attribute__((aligned(4))) TC; // TC sent to the ACTN task
55 ccsdsTelecommandPacket_t __attribute__((aligned(4))) TC; // TC sent to the ACTN task
56 size_t size; // size of the incoming TC packet
56 size_t size; // size of the incoming TC packet
57 unsigned char subtype; // subtype of the current TC packet
57 unsigned char subtype; // subtype of the current TC packet
58 unsigned char time[BYTES_PER_TIME];
58 unsigned char time[BYTES_PER_TIME];
59 rtems_id queue_rcv_id;
59 rtems_id queue_rcv_id;
60 rtems_id queue_snd_id;
60 rtems_id queue_snd_id;
61
61
62 memset(&TC, 0, sizeof(ccsdsTelecommandPacket_t));
62 memset(&TC, 0, sizeof(ccsdsTelecommandPacket_t));
63 size = 0;
63 size = 0;
64 queue_rcv_id = RTEMS_ID_NONE;
64 queue_rcv_id = RTEMS_ID_NONE;
65 queue_snd_id = RTEMS_ID_NONE;
65 queue_snd_id = RTEMS_ID_NONE;
66
66
67 status = get_message_queue_id_recv( &queue_rcv_id );
67 status = get_message_queue_id_recv( &queue_rcv_id );
68 if (status != RTEMS_SUCCESSFUL)
68 if (status != RTEMS_SUCCESSFUL)
69 {
69 {
70 PRINTF1("in ACTN *** ERR get_message_queue_id_recv %d\n", status)
70 PRINTF1("in ACTN *** ERR get_message_queue_id_recv %d\n", status)
71 }
71 }
72
72
73 status = get_message_queue_id_send( &queue_snd_id );
73 status = get_message_queue_id_send( &queue_snd_id );
74 if (status != RTEMS_SUCCESSFUL)
74 if (status != RTEMS_SUCCESSFUL)
75 {
75 {
76 PRINTF1("in ACTN *** ERR get_message_queue_id_send %d\n", status)
76 PRINTF1("in ACTN *** ERR get_message_queue_id_send %d\n", status)
77 }
77 }
78
78
79 result = LFR_SUCCESSFUL;
79 result = LFR_SUCCESSFUL;
80 subtype = 0; // subtype of the current TC packet
80 subtype = 0; // subtype of the current TC packet
81
81
82 BOOT_PRINTF("in ACTN *** \n");
82 BOOT_PRINTF("in ACTN *** \n");
83
83
84 while(1)
84 while(1)
85 {
85 {
86 status = rtems_message_queue_receive( queue_rcv_id, (char*) &TC, &size,
86 status = rtems_message_queue_receive( queue_rcv_id, (char*) &TC, &size,
87 RTEMS_WAIT, RTEMS_NO_TIMEOUT);
87 RTEMS_WAIT, RTEMS_NO_TIMEOUT);
88 getTime( time ); // set time to the current time
88 getTime( time ); // set time to the current time
89 if (status!=RTEMS_SUCCESSFUL)
89 if (status!=RTEMS_SUCCESSFUL)
90 {
90 {
91 PRINTF1("ERR *** in task ACTN *** error receiving a message, code %d \n", status)
91 PRINTF1("ERR *** in task ACTN *** error receiving a message, code %d \n", status)
92 }
92 }
93 else
93 else
94 {
94 {
95 subtype = TC.serviceSubType;
95 subtype = TC.serviceSubType;
96 switch(subtype)
96 switch(subtype)
97 {
97 {
98 case TC_SUBTYPE_RESET:
98 case TC_SUBTYPE_RESET:
99 result = action_reset( &TC, queue_snd_id, time );
99 result = action_reset( &TC, queue_snd_id, time );
100 close_action( &TC, result, queue_snd_id );
100 close_action( &TC, result, queue_snd_id );
101 break;
101 break;
102 case TC_SUBTYPE_LOAD_COMM:
102 case TC_SUBTYPE_LOAD_COMM:
103 result = action_load_common_par( &TC );
103 result = action_load_common_par( &TC );
104 close_action( &TC, result, queue_snd_id );
104 close_action( &TC, result, queue_snd_id );
105 break;
105 break;
106 case TC_SUBTYPE_LOAD_NORM:
106 case TC_SUBTYPE_LOAD_NORM:
107 result = action_load_normal_par( &TC, queue_snd_id, time );
107 result = action_load_normal_par( &TC, queue_snd_id, time );
108 close_action( &TC, result, queue_snd_id );
108 close_action( &TC, result, queue_snd_id );
109 break;
109 break;
110 case TC_SUBTYPE_LOAD_BURST:
110 case TC_SUBTYPE_LOAD_BURST:
111 result = action_load_burst_par( &TC, queue_snd_id, time );
111 result = action_load_burst_par( &TC, queue_snd_id, time );
112 close_action( &TC, result, queue_snd_id );
112 close_action( &TC, result, queue_snd_id );
113 break;
113 break;
114 case TC_SUBTYPE_LOAD_SBM1:
114 case TC_SUBTYPE_LOAD_SBM1:
115 result = action_load_sbm1_par( &TC, queue_snd_id, time );
115 result = action_load_sbm1_par( &TC, queue_snd_id, time );
116 close_action( &TC, result, queue_snd_id );
116 close_action( &TC, result, queue_snd_id );
117 break;
117 break;
118 case TC_SUBTYPE_LOAD_SBM2:
118 case TC_SUBTYPE_LOAD_SBM2:
119 result = action_load_sbm2_par( &TC, queue_snd_id, time );
119 result = action_load_sbm2_par( &TC, queue_snd_id, time );
120 close_action( &TC, result, queue_snd_id );
120 close_action( &TC, result, queue_snd_id );
121 break;
121 break;
122 case TC_SUBTYPE_DUMP:
122 case TC_SUBTYPE_DUMP:
123 result = action_dump_par( &TC, queue_snd_id );
123 result = action_dump_par( &TC, queue_snd_id );
124 close_action( &TC, result, queue_snd_id );
124 close_action( &TC, result, queue_snd_id );
125 break;
125 break;
126 case TC_SUBTYPE_ENTER:
126 case TC_SUBTYPE_ENTER:
127 result = action_enter_mode( &TC, queue_snd_id );
127 result = action_enter_mode( &TC, queue_snd_id );
128 close_action( &TC, result, queue_snd_id );
128 close_action( &TC, result, queue_snd_id );
129 break;
129 break;
130 case TC_SUBTYPE_UPDT_INFO:
130 case TC_SUBTYPE_UPDT_INFO:
131 result = action_update_info( &TC, queue_snd_id );
131 result = action_update_info( &TC, queue_snd_id );
132 close_action( &TC, result, queue_snd_id );
132 close_action( &TC, result, queue_snd_id );
133 break;
133 break;
134 case TC_SUBTYPE_EN_CAL:
134 case TC_SUBTYPE_EN_CAL:
135 result = action_enable_calibration( &TC, queue_snd_id, time );
135 result = action_enable_calibration( &TC, queue_snd_id, time );
136 close_action( &TC, result, queue_snd_id );
136 close_action( &TC, result, queue_snd_id );
137 break;
137 break;
138 case TC_SUBTYPE_DIS_CAL:
138 case TC_SUBTYPE_DIS_CAL:
139 result = action_disable_calibration( &TC, queue_snd_id, time );
139 result = action_disable_calibration( &TC, queue_snd_id, time );
140 close_action( &TC, result, queue_snd_id );
140 close_action( &TC, result, queue_snd_id );
141 break;
141 break;
142 case TC_SUBTYPE_LOAD_K:
142 case TC_SUBTYPE_LOAD_K:
143 result = action_load_kcoefficients( &TC, queue_snd_id, time );
143 result = action_load_kcoefficients( &TC, queue_snd_id, time );
144 close_action( &TC, result, queue_snd_id );
144 close_action( &TC, result, queue_snd_id );
145 break;
145 break;
146 case TC_SUBTYPE_DUMP_K:
146 case TC_SUBTYPE_DUMP_K:
147 result = action_dump_kcoefficients( &TC, queue_snd_id, time );
147 result = action_dump_kcoefficients( &TC, queue_snd_id, time );
148 close_action( &TC, result, queue_snd_id );
148 close_action( &TC, result, queue_snd_id );
149 break;
149 break;
150 case TC_SUBTYPE_LOAD_FBINS:
150 case TC_SUBTYPE_LOAD_FBINS:
151 result = action_load_fbins_mask( &TC, queue_snd_id, time );
151 result = action_load_fbins_mask( &TC, queue_snd_id, time );
152 close_action( &TC, result, queue_snd_id );
152 close_action( &TC, result, queue_snd_id );
153 break;
153 break;
154 case TC_SUBTYPE_LOAD_FILTER_PAR:
154 case TC_SUBTYPE_LOAD_FILTER_PAR:
155 result = action_load_filter_par( &TC, queue_snd_id, time );
155 result = action_load_filter_par( &TC, queue_snd_id, time );
156 close_action( &TC, result, queue_snd_id );
156 close_action( &TC, result, queue_snd_id );
157 break;
157 break;
158 case TC_SUBTYPE_UPDT_TIME:
158 case TC_SUBTYPE_UPDT_TIME:
159 result = action_update_time( &TC );
159 result = action_update_time( &TC );
160 close_action( &TC, result, queue_snd_id );
160 close_action( &TC, result, queue_snd_id );
161 break;
161 break;
162 default:
162 default:
163 break;
163 break;
164 }
164 }
165 }
165 }
166 }
166 }
167 }
167 }
168
168
169 //***********
169 //***********
170 // TC ACTIONS
170 // TC ACTIONS
171
171
172 int action_reset(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
172 int action_reset(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
173 {
173 {
174 /** This function executes specific actions when a TC_LFR_RESET TeleCommand has been received.
174 /** This function executes specific actions when a TC_LFR_RESET TeleCommand has been received.
175 *
175 *
176 * @param TC points to the TeleCommand packet that is being processed
176 * @param TC points to the TeleCommand packet that is being processed
177 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
177 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
178 *
178 *
179 */
179 */
180
180
181 PRINTF("this is the end!!!\n");
181 PRINTF("this is the end!!!\n");
182 #ifdef GCOV_ENABLED
182 #ifdef GCOV_ENABLED
183 #ifndef GCOV_USE_EXIT
183 #ifndef GCOV_USE_EXIT
184 extern void gcov_exit (void);
184 extern void gcov_exit (void);
185 gcov_exit();
185 gcov_exit();
186 #endif
186 #endif
187 #endif
187 #endif
188 exit(0);
188 exit(0);
189
189
190 send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time );
190 send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time );
191
191
192 return LFR_DEFAULT;
192 return LFR_DEFAULT;
193 }
193 }
194
194
195 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
195 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
196 {
196 {
197 /** This function executes specific actions when a TC_LFR_ENTER_MODE TeleCommand has been received.
197 /** This function executes specific actions when a TC_LFR_ENTER_MODE TeleCommand has been received.
198 *
198 *
199 * @param TC points to the TeleCommand packet that is being processed
199 * @param TC points to the TeleCommand packet that is being processed
200 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
200 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
201 *
201 *
202 */
202 */
203
203
204 rtems_status_code status;
204 rtems_status_code status;
205 unsigned char requestedMode;
205 unsigned char requestedMode;
206 unsigned int transitionCoarseTime;
206 unsigned int transitionCoarseTime;
207 unsigned char * bytePosPtr;
207 unsigned char * bytePosPtr;
208
208
209 bytePosPtr = (unsigned char *) &TC->packetID;
209 bytePosPtr = (unsigned char *) &TC->packetID;
210 requestedMode = bytePosPtr[ BYTE_POS_CP_MODE_LFR_SET ];
210 requestedMode = bytePosPtr[ BYTE_POS_CP_MODE_LFR_SET ];
211 copyInt32ByChar( (char*) &transitionCoarseTime, &bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME ] );
211 copyInt32ByChar( (char*) &transitionCoarseTime, &bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME ] );
212 transitionCoarseTime = transitionCoarseTime & COARSE_TIME_MASK;
212 transitionCoarseTime = transitionCoarseTime & COARSE_TIME_MASK;
213 status = check_mode_value( requestedMode );
213 status = check_mode_value( requestedMode );
214
214
215 if ( status != LFR_SUCCESSFUL ) // the mode value is inconsistent
215 if ( status != LFR_SUCCESSFUL ) // the mode value is inconsistent
216 {
216 {
217 send_tm_lfr_tc_exe_inconsistent( TC, queue_id, BYTE_POS_CP_MODE_LFR_SET, requestedMode );
217 send_tm_lfr_tc_exe_inconsistent( TC, queue_id, BYTE_POS_CP_MODE_LFR_SET, requestedMode );
218 }
218 }
219
219
220 else // the mode value is valid, check the transition
220 else // the mode value is valid, check the transition
221 {
221 {
222 status = check_mode_transition(requestedMode);
222 status = check_mode_transition(requestedMode);
223 if (status != LFR_SUCCESSFUL)
223 if (status != LFR_SUCCESSFUL)
224 {
224 {
225 PRINTF("ERR *** in action_enter_mode *** check_mode_transition\n")
225 PRINTF("ERR *** in action_enter_mode *** check_mode_transition\n")
226 send_tm_lfr_tc_exe_not_executable( TC, queue_id );
226 send_tm_lfr_tc_exe_not_executable( TC, queue_id );
227 }
227 }
228 }
228 }
229
229
230 if ( status == LFR_SUCCESSFUL ) // the transition is valid, check the date
230 if ( status == LFR_SUCCESSFUL ) // the transition is valid, check the date
231 {
231 {
232 status = check_transition_date( transitionCoarseTime );
232 status = check_transition_date( transitionCoarseTime );
233 if (status != LFR_SUCCESSFUL)
233 if (status != LFR_SUCCESSFUL)
234 {
234 {
235 PRINTF("ERR *** in action_enter_mode *** check_transition_date\n");
235 PRINTF("ERR *** in action_enter_mode *** check_transition_date\n");
236 send_tm_lfr_tc_exe_not_executable(TC, queue_id );
236 send_tm_lfr_tc_exe_not_executable(TC, queue_id );
237 }
237 }
238 }
238 }
239
239
240 if ( status == LFR_SUCCESSFUL ) // the date is valid, enter the mode
240 if ( status == LFR_SUCCESSFUL ) // the date is valid, enter the mode
241 {
241 {
242 PRINTF1("OK *** in action_enter_mode *** enter mode %d\n", requestedMode);
242 PRINTF1("OK *** in action_enter_mode *** enter mode %d\n", requestedMode);
243
243
244 switch(requestedMode)
244 switch(requestedMode)
245 {
245 {
246 case LFR_MODE_STANDBY:
246 case LFR_MODE_STANDBY:
247 status = enter_mode_standby();
247 status = enter_mode_standby();
248 break;
248 break;
249 case LFR_MODE_NORMAL:
249 case LFR_MODE_NORMAL:
250 status = enter_mode_normal( transitionCoarseTime );
250 status = enter_mode_normal( transitionCoarseTime );
251 break;
251 break;
252 case LFR_MODE_BURST:
252 case LFR_MODE_BURST:
253 status = enter_mode_burst( transitionCoarseTime );
253 status = enter_mode_burst( transitionCoarseTime );
254 break;
254 break;
255 case LFR_MODE_SBM1:
255 case LFR_MODE_SBM1:
256 status = enter_mode_sbm1( transitionCoarseTime );
256 status = enter_mode_sbm1( transitionCoarseTime );
257 break;
257 break;
258 case LFR_MODE_SBM2:
258 case LFR_MODE_SBM2:
259 status = enter_mode_sbm2( transitionCoarseTime );
259 status = enter_mode_sbm2( transitionCoarseTime );
260 break;
260 break;
261 default:
261 default:
262 break;
262 break;
263 }
263 }
264
264
265 if (status != RTEMS_SUCCESSFUL)
265 if (status != RTEMS_SUCCESSFUL)
266 {
266 {
267 status = LFR_EXE_ERROR;
267 status = LFR_EXE_ERROR;
268 }
268 }
269 }
269 }
270
270
271 return status;
271 return status;
272 }
272 }
273
273
274 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id)
274 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id)
275 {
275 {
276 /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been received.
276 /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been received.
277 *
277 *
278 * @param TC points to the TeleCommand packet that is being processed
278 * @param TC points to the TeleCommand packet that is being processed
279 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
279 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
280 *
280 *
281 * @return LFR directive status code:
281 * @return LFR directive status code:
282 * - LFR_DEFAULT
282 * - LFR_DEFAULT
283 * - LFR_SUCCESSFUL
283 * - LFR_SUCCESSFUL
284 *
284 *
285 */
285 */
286
286
287 unsigned int val;
287 unsigned int val;
288 unsigned int status;
288 unsigned int status;
289 unsigned char mode;
289 unsigned char mode;
290 unsigned char * bytePosPtr;
290 unsigned char * bytePosPtr;
291 int pos;
291 int pos;
292 float value;
292 float value;
293
293
294 pos = INIT_CHAR;
294 pos = INIT_CHAR;
295 value = INIT_FLOAT;
295 value = INIT_FLOAT;
296
296
297 status = LFR_DEFAULT;
297 status = LFR_DEFAULT;
298
298
299 bytePosPtr = (unsigned char *) &TC->packetID;
299 bytePosPtr = (unsigned char *) &TC->packetID;
300
300
301 // check LFR mode
301 // check LFR mode
302 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET5 ] & BITS_LFR_MODE) >> SHIFT_LFR_MODE;
302 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET5 ] & BITS_LFR_MODE) >> SHIFT_LFR_MODE;
303 status = check_update_info_hk_lfr_mode( mode );
303 status = check_update_info_hk_lfr_mode( mode );
304 if (status == LFR_SUCCESSFUL) // check TDS mode
304 if (status == LFR_SUCCESSFUL) // check TDS mode
305 {
305 {
306 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & BITS_TDS_MODE) >> SHIFT_TDS_MODE;
306 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & BITS_TDS_MODE) >> SHIFT_TDS_MODE;
307 status = check_update_info_hk_tds_mode( mode );
307 status = check_update_info_hk_tds_mode( mode );
308 }
308 }
309 if (status == LFR_SUCCESSFUL) // check THR mode
309 if (status == LFR_SUCCESSFUL) // check THR mode
310 {
310 {
311 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & BITS_THR_MODE);
311 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & BITS_THR_MODE);
312 status = check_update_info_hk_thr_mode( mode );
312 status = check_update_info_hk_thr_mode( mode );
313 }
313 }
314 if (status == LFR_SUCCESSFUL) // check reaction wheels frequencies
314 if (status == LFR_SUCCESSFUL) // check reaction wheels frequencies
315 {
315 {
316 status = check_all_sy_lfr_rw_f(TC, &pos, &value);
316 status = check_all_sy_lfr_rw_f(TC, &pos, &value);
317 }
317 }
318
318
319 // if the parameters checking succeeds, udpate all parameters
319 // if the parameters checking succeeds, udpate all parameters
320 if (status == LFR_SUCCESSFUL)
320 if (status == LFR_SUCCESSFUL)
321 {
321 {
322 // pa_bia_status_info
322 // pa_bia_status_info
323 // => pa_bia_mode_mux_set 3 bits
323 // => pa_bia_mode_mux_set 3 bits
324 // => pa_bia_mode_hv_enabled 1 bit
324 // => pa_bia_mode_hv_enabled 1 bit
325 // => pa_bia_mode_bias1_enabled 1 bit
325 // => pa_bia_mode_bias1_enabled 1 bit
326 // => pa_bia_mode_bias2_enabled 1 bit
326 // => pa_bia_mode_bias2_enabled 1 bit
327 // => pa_bia_mode_bias3_enabled 1 bit
327 // => pa_bia_mode_bias3_enabled 1 bit
328 // => pa_bia_on_off (cp_dpu_bias_on_off)
328 // => pa_bia_on_off (cp_dpu_bias_on_off)
329 pa_bia_status_info = bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET2 ] & BITS_BIA; // [1111 1110]
329 pa_bia_status_info = bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET2 ] & BITS_BIA; // [1111 1110]
330 pa_bia_status_info = pa_bia_status_info
330 pa_bia_status_info = pa_bia_status_info
331 | (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET1 ] & 1);
331 | (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET1 ] & 1);
332
332
333 // REACTION_WHEELS_FREQUENCY, copy the incoming parameters in the local variable (to be copied in HK packets)
333 // REACTION_WHEELS_FREQUENCY, copy the incoming parameters in the local variable (to be copied in HK packets)
334 getReactionWheelsFrequencies( TC );
334 getReactionWheelsFrequencies( TC );
335 set_hk_lfr_sc_rw_f_flags();
335 set_hk_lfr_sc_rw_f_flags();
336 build_sy_lfr_rw_masks();
336 build_sy_lfr_rw_masks();
337
337
338 // once the masks are built, they have to be merged with the fbins_mask
338 // once the masks are built, they have to be merged with the fbins_mask
339 merge_fbins_masks();
339 merge_fbins_masks();
340
340
341 // increase the TC_LFR_UPDATE_INFO counter
341 // increase the TC_LFR_UPDATE_INFO counter
342 if (status == LFR_SUCCESSFUL) // if the parameter check is successful
342 if (status == LFR_SUCCESSFUL) // if the parameter check is successful
343 {
343 {
344 val = (housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * CONST_256)
344 val = (housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * CONST_256)
345 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
345 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
346 val++;
346 val++;
347 housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
347 housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
348 housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char) (val);
348 housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char) (val);
349 }
349 }
350 }
350 }
351
351
352 return status;
352 return status;
353 }
353 }
354
354
355 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
355 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
356 {
356 {
357 /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has been received.
357 /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has been received.
358 *
358 *
359 * @param TC points to the TeleCommand packet that is being processed
359 * @param TC points to the TeleCommand packet that is being processed
360 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
360 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
361 *
361 *
362 */
362 */
363
363
364 int result;
364 int result;
365
365
366 result = LFR_DEFAULT;
366 result = LFR_DEFAULT;
367
367
368 setCalibration( true );
368 setCalibration( true );
369
369
370 result = LFR_SUCCESSFUL;
370 result = LFR_SUCCESSFUL;
371
371
372 return result;
372 return result;
373 }
373 }
374
374
375 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
375 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
376 {
376 {
377 /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has been received.
377 /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has been received.
378 *
378 *
379 * @param TC points to the TeleCommand packet that is being processed
379 * @param TC points to the TeleCommand packet that is being processed
380 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
380 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
381 *
381 *
382 */
382 */
383
383
384 int result;
384 int result;
385
385
386 result = LFR_DEFAULT;
386 result = LFR_DEFAULT;
387
387
388 setCalibration( false );
388 setCalibration( false );
389
389
390 result = LFR_SUCCESSFUL;
390 result = LFR_SUCCESSFUL;
391
391
392 return result;
392 return result;
393 }
393 }
394
394
395 int action_update_time(ccsdsTelecommandPacket_t *TC)
395 int action_update_time(ccsdsTelecommandPacket_t *TC)
396 {
396 {
397 /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been received.
397 /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been received.
398 *
398 *
399 * @param TC points to the TeleCommand packet that is being processed
399 * @param TC points to the TeleCommand packet that is being processed
400 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
400 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
401 *
401 *
402 * @return LFR_SUCCESSFUL
402 * @return LFR_SUCCESSFUL
403 *
403 *
404 */
404 */
405
405
406 unsigned int val;
406 unsigned int val;
407
407
408 time_management_regs->coarse_time_load = (TC->dataAndCRC[BYTE_0] << SHIFT_3_BYTES)
408 time_management_regs->coarse_time_load = (TC->dataAndCRC[BYTE_0] << SHIFT_3_BYTES)
409 + (TC->dataAndCRC[BYTE_1] << SHIFT_2_BYTES)
409 + (TC->dataAndCRC[BYTE_1] << SHIFT_2_BYTES)
410 + (TC->dataAndCRC[BYTE_2] << SHIFT_1_BYTE)
410 + (TC->dataAndCRC[BYTE_2] << SHIFT_1_BYTE)
411 + TC->dataAndCRC[BYTE_3];
411 + TC->dataAndCRC[BYTE_3];
412
412
413 val = (housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * CONST_256)
413 val = (housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * CONST_256)
414 + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
414 + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
415 val++;
415 val++;
416 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
416 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
417 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
417 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
418
418
419 oneTcLfrUpdateTimeReceived = 1;
419 oneTcLfrUpdateTimeReceived = 1;
420
420
421 return LFR_SUCCESSFUL;
421 return LFR_SUCCESSFUL;
422 }
422 }
423
423
424 //*******************
424 //*******************
425 // ENTERING THE MODES
425 // ENTERING THE MODES
426 int check_mode_value( unsigned char requestedMode )
426 int check_mode_value( unsigned char requestedMode )
427 {
427 {
428 int status;
428 int status;
429
429
430 status = LFR_DEFAULT;
430 status = LFR_DEFAULT;
431
431
432 if ( (requestedMode != LFR_MODE_STANDBY)
432 if ( (requestedMode != LFR_MODE_STANDBY)
433 && (requestedMode != LFR_MODE_NORMAL) && (requestedMode != LFR_MODE_BURST)
433 && (requestedMode != LFR_MODE_NORMAL) && (requestedMode != LFR_MODE_BURST)
434 && (requestedMode != LFR_MODE_SBM1) && (requestedMode != LFR_MODE_SBM2) )
434 && (requestedMode != LFR_MODE_SBM1) && (requestedMode != LFR_MODE_SBM2) )
435 {
435 {
436 status = LFR_DEFAULT;
436 status = LFR_DEFAULT;
437 }
437 }
438 else
438 else
439 {
439 {
440 status = LFR_SUCCESSFUL;
440 status = LFR_SUCCESSFUL;
441 }
441 }
442
442
443 return status;
443 return status;
444 }
444 }
445
445
446 int check_mode_transition( unsigned char requestedMode )
446 int check_mode_transition( unsigned char requestedMode )
447 {
447 {
448 /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
448 /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
449 *
449 *
450 * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
450 * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
451 *
451 *
452 * @return LFR directive status codes:
452 * @return LFR directive status codes:
453 * - LFR_SUCCESSFUL - the transition is authorized
453 * - LFR_SUCCESSFUL - the transition is authorized
454 * - LFR_DEFAULT - the transition is not authorized
454 * - LFR_DEFAULT - the transition is not authorized
455 *
455 *
456 */
456 */
457
457
458 int status;
458 int status;
459
459
460 switch (requestedMode)
460 switch (requestedMode)
461 {
461 {
462 case LFR_MODE_STANDBY:
462 case LFR_MODE_STANDBY:
463 if ( lfrCurrentMode == LFR_MODE_STANDBY ) {
463 if ( lfrCurrentMode == LFR_MODE_STANDBY ) {
464 status = LFR_DEFAULT;
464 status = LFR_DEFAULT;
465 }
465 }
466 else
466 else
467 {
467 {
468 status = LFR_SUCCESSFUL;
468 status = LFR_SUCCESSFUL;
469 }
469 }
470 break;
470 break;
471 case LFR_MODE_NORMAL:
471 case LFR_MODE_NORMAL:
472 if ( lfrCurrentMode == LFR_MODE_NORMAL ) {
472 if ( lfrCurrentMode == LFR_MODE_NORMAL ) {
473 status = LFR_DEFAULT;
473 status = LFR_DEFAULT;
474 }
474 }
475 else {
475 else {
476 status = LFR_SUCCESSFUL;
476 status = LFR_SUCCESSFUL;
477 }
477 }
478 break;
478 break;
479 case LFR_MODE_BURST:
479 case LFR_MODE_BURST:
480 if ( lfrCurrentMode == LFR_MODE_BURST ) {
480 if ( lfrCurrentMode == LFR_MODE_BURST ) {
481 status = LFR_DEFAULT;
481 status = LFR_DEFAULT;
482 }
482 }
483 else {
483 else {
484 status = LFR_SUCCESSFUL;
484 status = LFR_SUCCESSFUL;
485 }
485 }
486 break;
486 break;
487 case LFR_MODE_SBM1:
487 case LFR_MODE_SBM1:
488 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
488 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
489 status = LFR_DEFAULT;
489 status = LFR_DEFAULT;
490 }
490 }
491 else {
491 else {
492 status = LFR_SUCCESSFUL;
492 status = LFR_SUCCESSFUL;
493 }
493 }
494 break;
494 break;
495 case LFR_MODE_SBM2:
495 case LFR_MODE_SBM2:
496 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
496 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
497 status = LFR_DEFAULT;
497 status = LFR_DEFAULT;
498 }
498 }
499 else {
499 else {
500 status = LFR_SUCCESSFUL;
500 status = LFR_SUCCESSFUL;
501 }
501 }
502 break;
502 break;
503 default:
503 default:
504 status = LFR_DEFAULT;
504 status = LFR_DEFAULT;
505 break;
505 break;
506 }
506 }
507
507
508 return status;
508 return status;
509 }
509 }
510
510
511 void update_last_valid_transition_date( unsigned int transitionCoarseTime )
511 void update_last_valid_transition_date( unsigned int transitionCoarseTime )
512 {
512 {
513 if (transitionCoarseTime == 0)
513 if (transitionCoarseTime == 0)
514 {
514 {
515 lastValidEnterModeTime = time_management_regs->coarse_time + 1;
515 lastValidEnterModeTime = time_management_regs->coarse_time + 1;
516 PRINTF1("lastValidEnterModeTime = 0x%x (transitionCoarseTime = 0 => coarse_time+1)\n", lastValidEnterModeTime);
516 PRINTF1("lastValidEnterModeTime = 0x%x (transitionCoarseTime = 0 => coarse_time+1)\n", lastValidEnterModeTime);
517 }
517 }
518 else
518 else
519 {
519 {
520 lastValidEnterModeTime = transitionCoarseTime;
520 lastValidEnterModeTime = transitionCoarseTime;
521 PRINTF1("lastValidEnterModeTime = 0x%x\n", transitionCoarseTime);
521 PRINTF1("lastValidEnterModeTime = 0x%x\n", transitionCoarseTime);
522 }
522 }
523 }
523 }
524
524
525 int check_transition_date( unsigned int transitionCoarseTime )
525 int check_transition_date( unsigned int transitionCoarseTime )
526 {
526 {
527 int status;
527 int status;
528 unsigned int localCoarseTime;
528 unsigned int localCoarseTime;
529 unsigned int deltaCoarseTime;
529 unsigned int deltaCoarseTime;
530
530
531 status = LFR_SUCCESSFUL;
531 status = LFR_SUCCESSFUL;
532
532
533 if (transitionCoarseTime == 0) // transition time = 0 means an instant transition
533 if (transitionCoarseTime == 0) // transition time = 0 means an instant transition
534 {
534 {
535 status = LFR_SUCCESSFUL;
535 status = LFR_SUCCESSFUL;
536 }
536 }
537 else
537 else
538 {
538 {
539 localCoarseTime = time_management_regs->coarse_time & COARSE_TIME_MASK;
539 localCoarseTime = time_management_regs->coarse_time & COARSE_TIME_MASK;
540
540
541 PRINTF2("localTime = %x, transitionTime = %x\n", localCoarseTime, transitionCoarseTime);
541 PRINTF2("localTime = %x, transitionTime = %x\n", localCoarseTime, transitionCoarseTime);
542
542
543 if ( transitionCoarseTime <= localCoarseTime ) // SSS-CP-EQS-322
543 if ( transitionCoarseTime <= localCoarseTime ) // SSS-CP-EQS-322
544 {
544 {
545 status = LFR_DEFAULT;
545 status = LFR_DEFAULT;
546 PRINTF("ERR *** in check_transition_date *** transitionCoarseTime <= localCoarseTime\n");
546 PRINTF("ERR *** in check_transition_date *** transitionCoarseTime <= localCoarseTime\n");
547 }
547 }
548
548
549 if (status == LFR_SUCCESSFUL)
549 if (status == LFR_SUCCESSFUL)
550 {
550 {
551 deltaCoarseTime = transitionCoarseTime - localCoarseTime;
551 deltaCoarseTime = transitionCoarseTime - localCoarseTime;
552 if ( deltaCoarseTime > MAX_DELTA_COARSE_TIME ) // SSS-CP-EQS-323
552 if ( deltaCoarseTime > MAX_DELTA_COARSE_TIME ) // SSS-CP-EQS-323
553 {
553 {
554 status = LFR_DEFAULT;
554 status = LFR_DEFAULT;
555 PRINTF1("ERR *** in check_transition_date *** deltaCoarseTime = %x\n", deltaCoarseTime)
555 PRINTF1("ERR *** in check_transition_date *** deltaCoarseTime = %x\n", deltaCoarseTime)
556 }
556 }
557 }
557 }
558 }
558 }
559
559
560 return status;
560 return status;
561 }
561 }
562
562
563 int restart_asm_activities( unsigned char lfrRequestedMode )
563 int restart_asm_activities( unsigned char lfrRequestedMode )
564 {
564 {
565 rtems_status_code status;
565 rtems_status_code status;
566
566
567 status = stop_spectral_matrices();
567 status = stop_spectral_matrices();
568
568
569 thisIsAnASMRestart = 1;
569 thisIsAnASMRestart = 1;
570
570
571 status = restart_asm_tasks( lfrRequestedMode );
571 status = restart_asm_tasks( lfrRequestedMode );
572
572
573 launch_spectral_matrix();
573 launch_spectral_matrix();
574
574
575 return status;
575 return status;
576 }
576 }
577
577
578 int stop_spectral_matrices( void )
578 int stop_spectral_matrices( void )
579 {
579 {
580 /** This function stops and restarts the current mode average spectral matrices activities.
580 /** This function stops and restarts the current mode average spectral matrices activities.
581 *
581 *
582 * @return RTEMS directive status codes:
582 * @return RTEMS directive status codes:
583 * - RTEMS_SUCCESSFUL - task restarted successfully
583 * - RTEMS_SUCCESSFUL - task restarted successfully
584 * - RTEMS_INVALID_ID - task id invalid
584 * - RTEMS_INVALID_ID - task id invalid
585 * - RTEMS_ALREADY_SUSPENDED - task already suspended
585 * - RTEMS_ALREADY_SUSPENDED - task already suspended
586 *
586 *
587 */
587 */
588
588
589 rtems_status_code status;
589 rtems_status_code status;
590
590
591 status = RTEMS_SUCCESSFUL;
591 status = RTEMS_SUCCESSFUL;
592
592
593 // (1) mask interruptions
593 // (1) mask interruptions
594 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // mask spectral matrix interrupt
594 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // mask spectral matrix interrupt
595
595
596 // (2) reset spectral matrices registers
596 // (2) reset spectral matrices registers
597 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
597 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
598 reset_sm_status();
598 reset_sm_status();
599
599
600 // (3) clear interruptions
600 // (3) clear interruptions
601 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
601 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
602
602
603 // suspend several tasks
603 // suspend several tasks
604 if (lfrCurrentMode != LFR_MODE_STANDBY) {
604 if (lfrCurrentMode != LFR_MODE_STANDBY) {
605 status = suspend_asm_tasks();
605 status = suspend_asm_tasks();
606 }
606 }
607
607
608 if (status != RTEMS_SUCCESSFUL)
608 if (status != RTEMS_SUCCESSFUL)
609 {
609 {
610 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
610 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
611 }
611 }
612
612
613 return status;
613 return status;
614 }
614 }
615
615
616 int stop_current_mode( void )
616 int stop_current_mode( void )
617 {
617 {
618 /** This function stops the current mode by masking interrupt lines and suspending science tasks.
618 /** This function stops the current mode by masking interrupt lines and suspending science tasks.
619 *
619 *
620 * @return RTEMS directive status codes:
620 * @return RTEMS directive status codes:
621 * - RTEMS_SUCCESSFUL - task restarted successfully
621 * - RTEMS_SUCCESSFUL - task restarted successfully
622 * - RTEMS_INVALID_ID - task id invalid
622 * - RTEMS_INVALID_ID - task id invalid
623 * - RTEMS_ALREADY_SUSPENDED - task already suspended
623 * - RTEMS_ALREADY_SUSPENDED - task already suspended
624 *
624 *
625 */
625 */
626
626
627 rtems_status_code status;
627 rtems_status_code status;
628
628
629 status = RTEMS_SUCCESSFUL;
629 status = RTEMS_SUCCESSFUL;
630
630
631 // (1) mask interruptions
631 // (1) mask interruptions
632 LEON_Mask_interrupt( IRQ_WAVEFORM_PICKER ); // mask waveform picker interrupt
632 LEON_Mask_interrupt( IRQ_WAVEFORM_PICKER ); // mask waveform picker interrupt
633 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
633 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
634
634
635 // (2) reset waveform picker registers
635 // (2) reset waveform picker registers
636 reset_wfp_burst_enable(); // reset burst and enable bits
636 reset_wfp_burst_enable(); // reset burst and enable bits
637 reset_wfp_status(); // reset all the status bits
637 reset_wfp_status(); // reset all the status bits
638
638
639 // (3) reset spectral matrices registers
639 // (3) reset spectral matrices registers
640 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
640 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
641 reset_sm_status();
641 reset_sm_status();
642
642
643 // reset lfr VHDL module
643 // reset lfr VHDL module
644 reset_lfr();
644 reset_lfr();
645
645
646 reset_extractSWF(); // reset the extractSWF flag to false
646 reset_extractSWF(); // reset the extractSWF flag to false
647
647
648 // (4) clear interruptions
648 // (4) clear interruptions
649 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER ); // clear waveform picker interrupt
649 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER ); // clear waveform picker interrupt
650 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
650 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
651
651
652 // suspend several tasks
652 // suspend several tasks
653 if (lfrCurrentMode != LFR_MODE_STANDBY) {
653 if (lfrCurrentMode != LFR_MODE_STANDBY) {
654 status = suspend_science_tasks();
654 status = suspend_science_tasks();
655 }
655 }
656
656
657 if (status != RTEMS_SUCCESSFUL)
657 if (status != RTEMS_SUCCESSFUL)
658 {
658 {
659 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
659 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
660 }
660 }
661
661
662 return status;
662 return status;
663 }
663 }
664
664
665 int enter_mode_standby( void )
665 int enter_mode_standby( void )
666 {
666 {
667 /** This function is used to put LFR in the STANDBY mode.
667 /** This function is used to put LFR in the STANDBY mode.
668 *
668 *
669 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
669 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
670 *
670 *
671 * @return RTEMS directive status codes:
671 * @return RTEMS directive status codes:
672 * - RTEMS_SUCCESSFUL - task restarted successfully
672 * - RTEMS_SUCCESSFUL - task restarted successfully
673 * - RTEMS_INVALID_ID - task id invalid
673 * - RTEMS_INVALID_ID - task id invalid
674 * - RTEMS_INCORRECT_STATE - task never started
674 * - RTEMS_INCORRECT_STATE - task never started
675 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
675 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
676 *
676 *
677 * The STANDBY mode does not depends on a specific transition date, the effect of the TC_LFR_ENTER_MODE
677 * The STANDBY mode does not depends on a specific transition date, the effect of the TC_LFR_ENTER_MODE
678 * is immediate.
678 * is immediate.
679 *
679 *
680 */
680 */
681
681
682 int status;
682 int status;
683
683
684 status = stop_current_mode(); // STOP THE CURRENT MODE
684 status = stop_current_mode(); // STOP THE CURRENT MODE
685
685
686 #ifdef PRINT_TASK_STATISTICS
686 #ifdef PRINT_TASK_STATISTICS
687 rtems_cpu_usage_report();
687 rtems_cpu_usage_report();
688 #endif
688 #endif
689
689
690 #ifdef PRINT_STACK_REPORT
690 #ifdef PRINT_STACK_REPORT
691 PRINTF("stack report selected\n")
691 PRINTF("stack report selected\n")
692 rtems_stack_checker_report_usage();
692 rtems_stack_checker_report_usage();
693 #endif
693 #endif
694
694
695 return status;
695 return status;
696 }
696 }
697
697
698 int enter_mode_normal( unsigned int transitionCoarseTime )
698 int enter_mode_normal( unsigned int transitionCoarseTime )
699 {
699 {
700 /** This function is used to start the NORMAL mode.
700 /** This function is used to start the NORMAL mode.
701 *
701 *
702 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
702 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
703 *
703 *
704 * @return RTEMS directive status codes:
704 * @return RTEMS directive status codes:
705 * - RTEMS_SUCCESSFUL - task restarted successfully
705 * - RTEMS_SUCCESSFUL - task restarted successfully
706 * - RTEMS_INVALID_ID - task id invalid
706 * - RTEMS_INVALID_ID - task id invalid
707 * - RTEMS_INCORRECT_STATE - task never started
707 * - RTEMS_INCORRECT_STATE - task never started
708 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
708 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
709 *
709 *
710 * The way the NORMAL mode is started depends on the LFR current mode. If LFR is in SBM1 or SBM2,
710 * The way the NORMAL mode is started depends on the LFR current mode. If LFR is in SBM1 or SBM2,
711 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected.
711 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected.
712 *
712 *
713 */
713 */
714
714
715 int status;
715 int status;
716
716
717 #ifdef PRINT_TASK_STATISTICS
717 #ifdef PRINT_TASK_STATISTICS
718 rtems_cpu_usage_reset();
718 rtems_cpu_usage_reset();
719 #endif
719 #endif
720
720
721 status = RTEMS_UNSATISFIED;
721 status = RTEMS_UNSATISFIED;
722
722
723 switch( lfrCurrentMode )
723 switch( lfrCurrentMode )
724 {
724 {
725 case LFR_MODE_STANDBY:
725 case LFR_MODE_STANDBY:
726 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart science tasks
726 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart science tasks
727 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
727 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
728 {
728 {
729 launch_spectral_matrix( );
729 launch_spectral_matrix( );
730 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
730 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
731 }
731 }
732 break;
732 break;
733 case LFR_MODE_BURST:
733 case LFR_MODE_BURST:
734 status = stop_current_mode(); // stop the current mode
734 status = stop_current_mode(); // stop the current mode
735 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart the science tasks
735 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart the science tasks
736 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
736 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
737 {
737 {
738 launch_spectral_matrix( );
738 launch_spectral_matrix( );
739 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
739 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
740 }
740 }
741 break;
741 break;
742 case LFR_MODE_SBM1:
742 case LFR_MODE_SBM1:
743 status = restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
743 status = restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
744 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
744 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
745 update_last_valid_transition_date( transitionCoarseTime );
745 update_last_valid_transition_date( transitionCoarseTime );
746 break;
746 break;
747 case LFR_MODE_SBM2:
747 case LFR_MODE_SBM2:
748 status = restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
748 status = restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
749 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
749 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
750 update_last_valid_transition_date( transitionCoarseTime );
750 update_last_valid_transition_date( transitionCoarseTime );
751 break;
751 break;
752 default:
752 default:
753 break;
753 break;
754 }
754 }
755
755
756 if (status != RTEMS_SUCCESSFUL)
756 if (status != RTEMS_SUCCESSFUL)
757 {
757 {
758 PRINTF1("ERR *** in enter_mode_normal *** status = %d\n", status)
758 PRINTF1("ERR *** in enter_mode_normal *** status = %d\n", status)
759 status = RTEMS_UNSATISFIED;
759 status = RTEMS_UNSATISFIED;
760 }
760 }
761
761
762 return status;
762 return status;
763 }
763 }
764
764
765 int enter_mode_burst( unsigned int transitionCoarseTime )
765 int enter_mode_burst( unsigned int transitionCoarseTime )
766 {
766 {
767 /** This function is used to start the BURST mode.
767 /** This function is used to start the BURST mode.
768 *
768 *
769 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
769 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
770 *
770 *
771 * @return RTEMS directive status codes:
771 * @return RTEMS directive status codes:
772 * - RTEMS_SUCCESSFUL - task restarted successfully
772 * - RTEMS_SUCCESSFUL - task restarted successfully
773 * - RTEMS_INVALID_ID - task id invalid
773 * - RTEMS_INVALID_ID - task id invalid
774 * - RTEMS_INCORRECT_STATE - task never started
774 * - RTEMS_INCORRECT_STATE - task never started
775 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
775 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
776 *
776 *
777 * The way the BURST mode is started does not depend on the LFR current mode.
777 * The way the BURST mode is started does not depend on the LFR current mode.
778 *
778 *
779 */
779 */
780
780
781
781
782 int status;
782 int status;
783
783
784 #ifdef PRINT_TASK_STATISTICS
784 #ifdef PRINT_TASK_STATISTICS
785 rtems_cpu_usage_reset();
785 rtems_cpu_usage_reset();
786 #endif
786 #endif
787
787
788 status = stop_current_mode(); // stop the current mode
788 status = stop_current_mode(); // stop the current mode
789 status = restart_science_tasks( LFR_MODE_BURST ); // restart the science tasks
789 status = restart_science_tasks( LFR_MODE_BURST ); // restart the science tasks
790 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
790 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
791 {
791 {
792 launch_spectral_matrix( );
792 launch_spectral_matrix( );
793 launch_waveform_picker( LFR_MODE_BURST, transitionCoarseTime );
793 launch_waveform_picker( LFR_MODE_BURST, transitionCoarseTime );
794 }
794 }
795
795
796 if (status != RTEMS_SUCCESSFUL)
796 if (status != RTEMS_SUCCESSFUL)
797 {
797 {
798 PRINTF1("ERR *** in enter_mode_burst *** status = %d\n", status)
798 PRINTF1("ERR *** in enter_mode_burst *** status = %d\n", status)
799 status = RTEMS_UNSATISFIED;
799 status = RTEMS_UNSATISFIED;
800 }
800 }
801
801
802 return status;
802 return status;
803 }
803 }
804
804
805 int enter_mode_sbm1( unsigned int transitionCoarseTime )
805 int enter_mode_sbm1( unsigned int transitionCoarseTime )
806 {
806 {
807 /** This function is used to start the SBM1 mode.
807 /** This function is used to start the SBM1 mode.
808 *
808 *
809 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
809 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
810 *
810 *
811 * @return RTEMS directive status codes:
811 * @return RTEMS directive status codes:
812 * - RTEMS_SUCCESSFUL - task restarted successfully
812 * - RTEMS_SUCCESSFUL - task restarted successfully
813 * - RTEMS_INVALID_ID - task id invalid
813 * - RTEMS_INVALID_ID - task id invalid
814 * - RTEMS_INCORRECT_STATE - task never started
814 * - RTEMS_INCORRECT_STATE - task never started
815 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
815 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
816 *
816 *
817 * The way the SBM1 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM2,
817 * The way the SBM1 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM2,
818 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
818 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
819 * cases, the acquisition is completely restarted.
819 * cases, the acquisition is completely restarted.
820 *
820 *
821 */
821 */
822
822
823 int status;
823 int status;
824
824
825 #ifdef PRINT_TASK_STATISTICS
825 #ifdef PRINT_TASK_STATISTICS
826 rtems_cpu_usage_reset();
826 rtems_cpu_usage_reset();
827 #endif
827 #endif
828
828
829 status = RTEMS_UNSATISFIED;
829 status = RTEMS_UNSATISFIED;
830
830
831 switch( lfrCurrentMode )
831 switch( lfrCurrentMode )
832 {
832 {
833 case LFR_MODE_STANDBY:
833 case LFR_MODE_STANDBY:
834 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart science tasks
834 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart science tasks
835 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
835 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
836 {
836 {
837 launch_spectral_matrix( );
837 launch_spectral_matrix( );
838 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
838 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
839 }
839 }
840 break;
840 break;
841 case LFR_MODE_NORMAL: // lfrCurrentMode will be updated after the execution of close_action
841 case LFR_MODE_NORMAL: // lfrCurrentMode will be updated after the execution of close_action
842 status = restart_asm_activities( LFR_MODE_SBM1 );
842 status = restart_asm_activities( LFR_MODE_SBM1 );
843 status = LFR_SUCCESSFUL;
843 status = LFR_SUCCESSFUL;
844 update_last_valid_transition_date( transitionCoarseTime );
844 update_last_valid_transition_date( transitionCoarseTime );
845 break;
845 break;
846 case LFR_MODE_BURST:
846 case LFR_MODE_BURST:
847 status = stop_current_mode(); // stop the current mode
847 status = stop_current_mode(); // stop the current mode
848 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart the science tasks
848 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart the science tasks
849 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
849 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
850 {
850 {
851 launch_spectral_matrix( );
851 launch_spectral_matrix( );
852 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
852 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
853 }
853 }
854 break;
854 break;
855 case LFR_MODE_SBM2:
855 case LFR_MODE_SBM2:
856 status = restart_asm_activities( LFR_MODE_SBM1 );
856 status = restart_asm_activities( LFR_MODE_SBM1 );
857 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
857 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
858 update_last_valid_transition_date( transitionCoarseTime );
858 update_last_valid_transition_date( transitionCoarseTime );
859 break;
859 break;
860 default:
860 default:
861 break;
861 break;
862 }
862 }
863
863
864 if (status != RTEMS_SUCCESSFUL)
864 if (status != RTEMS_SUCCESSFUL)
865 {
865 {
866 PRINTF1("ERR *** in enter_mode_sbm1 *** status = %d\n", status);
866 PRINTF1("ERR *** in enter_mode_sbm1 *** status = %d\n", status);
867 status = RTEMS_UNSATISFIED;
867 status = RTEMS_UNSATISFIED;
868 }
868 }
869
869
870 return status;
870 return status;
871 }
871 }
872
872
873 int enter_mode_sbm2( unsigned int transitionCoarseTime )
873 int enter_mode_sbm2( unsigned int transitionCoarseTime )
874 {
874 {
875 /** This function is used to start the SBM2 mode.
875 /** This function is used to start the SBM2 mode.
876 *
876 *
877 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
877 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
878 *
878 *
879 * @return RTEMS directive status codes:
879 * @return RTEMS directive status codes:
880 * - RTEMS_SUCCESSFUL - task restarted successfully
880 * - RTEMS_SUCCESSFUL - task restarted successfully
881 * - RTEMS_INVALID_ID - task id invalid
881 * - RTEMS_INVALID_ID - task id invalid
882 * - RTEMS_INCORRECT_STATE - task never started
882 * - RTEMS_INCORRECT_STATE - task never started
883 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
883 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
884 *
884 *
885 * The way the SBM2 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM1,
885 * The way the SBM2 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM1,
886 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
886 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
887 * cases, the acquisition is completely restarted.
887 * cases, the acquisition is completely restarted.
888 *
888 *
889 */
889 */
890
890
891 int status;
891 int status;
892
892
893 #ifdef PRINT_TASK_STATISTICS
893 #ifdef PRINT_TASK_STATISTICS
894 rtems_cpu_usage_reset();
894 rtems_cpu_usage_reset();
895 #endif
895 #endif
896
896
897 status = RTEMS_UNSATISFIED;
897 status = RTEMS_UNSATISFIED;
898
898
899 switch( lfrCurrentMode )
899 switch( lfrCurrentMode )
900 {
900 {
901 case LFR_MODE_STANDBY:
901 case LFR_MODE_STANDBY:
902 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart science tasks
902 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart science tasks
903 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
903 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
904 {
904 {
905 launch_spectral_matrix( );
905 launch_spectral_matrix( );
906 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
906 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
907 }
907 }
908 break;
908 break;
909 case LFR_MODE_NORMAL:
909 case LFR_MODE_NORMAL:
910 status = restart_asm_activities( LFR_MODE_SBM2 );
910 status = restart_asm_activities( LFR_MODE_SBM2 );
911 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
911 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
912 update_last_valid_transition_date( transitionCoarseTime );
912 update_last_valid_transition_date( transitionCoarseTime );
913 break;
913 break;
914 case LFR_MODE_BURST:
914 case LFR_MODE_BURST:
915 status = stop_current_mode(); // stop the current mode
915 status = stop_current_mode(); // stop the current mode
916 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart the science tasks
916 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart the science tasks
917 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
917 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
918 {
918 {
919 launch_spectral_matrix( );
919 launch_spectral_matrix( );
920 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
920 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
921 }
921 }
922 break;
922 break;
923 case LFR_MODE_SBM1:
923 case LFR_MODE_SBM1:
924 status = restart_asm_activities( LFR_MODE_SBM2 );
924 status = restart_asm_activities( LFR_MODE_SBM2 );
925 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
925 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
926 update_last_valid_transition_date( transitionCoarseTime );
926 update_last_valid_transition_date( transitionCoarseTime );
927 break;
927 break;
928 default:
928 default:
929 break;
929 break;
930 }
930 }
931
931
932 if (status != RTEMS_SUCCESSFUL)
932 if (status != RTEMS_SUCCESSFUL)
933 {
933 {
934 PRINTF1("ERR *** in enter_mode_sbm2 *** status = %d\n", status)
934 PRINTF1("ERR *** in enter_mode_sbm2 *** status = %d\n", status)
935 status = RTEMS_UNSATISFIED;
935 status = RTEMS_UNSATISFIED;
936 }
936 }
937
937
938 return status;
938 return status;
939 }
939 }
940
940
941 int restart_science_tasks( unsigned char lfrRequestedMode )
941 int restart_science_tasks( unsigned char lfrRequestedMode )
942 {
942 {
943 /** This function is used to restart all science tasks.
943 /** This function is used to restart all science tasks.
944 *
944 *
945 * @return RTEMS directive status codes:
945 * @return RTEMS directive status codes:
946 * - RTEMS_SUCCESSFUL - task restarted successfully
946 * - RTEMS_SUCCESSFUL - task restarted successfully
947 * - RTEMS_INVALID_ID - task id invalid
947 * - RTEMS_INVALID_ID - task id invalid
948 * - RTEMS_INCORRECT_STATE - task never started
948 * - RTEMS_INCORRECT_STATE - task never started
949 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
949 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
950 *
950 *
951 * Science tasks are AVF0, PRC0, WFRM, CWF3, CW2, CWF1
951 * Science tasks are AVF0, PRC0, WFRM, CWF3, CW2, CWF1
952 *
952 *
953 */
953 */
954
954
955 rtems_status_code status[NB_SCIENCE_TASKS];
955 rtems_status_code status[NB_SCIENCE_TASKS];
956 rtems_status_code ret;
956 rtems_status_code ret;
957
957
958 ret = RTEMS_SUCCESSFUL;
958 ret = RTEMS_SUCCESSFUL;
959
959
960 status[STATUS_0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
960 status[STATUS_0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
961 if (status[STATUS_0] != RTEMS_SUCCESSFUL)
961 if (status[STATUS_0] != RTEMS_SUCCESSFUL)
962 {
962 {
963 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[STATUS_0])
963 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[STATUS_0])
964 }
964 }
965
965
966 status[STATUS_1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
966 status[STATUS_1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
967 if (status[STATUS_1] != RTEMS_SUCCESSFUL)
967 if (status[STATUS_1] != RTEMS_SUCCESSFUL)
968 {
968 {
969 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[STATUS_1])
969 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[STATUS_1])
970 }
970 }
971
971
972 status[STATUS_2] = rtems_task_restart( Task_id[TASKID_WFRM],1 );
972 status[STATUS_2] = rtems_task_restart( Task_id[TASKID_WFRM],1 );
973 if (status[STATUS_2] != RTEMS_SUCCESSFUL)
973 if (status[STATUS_2] != RTEMS_SUCCESSFUL)
974 {
974 {
975 PRINTF1("in restart_science_task *** WFRM ERR %d\n", status[STATUS_2])
975 PRINTF1("in restart_science_task *** WFRM ERR %d\n", status[STATUS_2])
976 }
976 }
977
977
978 status[STATUS_3] = rtems_task_restart( Task_id[TASKID_CWF3],1 );
978 status[STATUS_3] = rtems_task_restart( Task_id[TASKID_CWF3],1 );
979 if (status[STATUS_3] != RTEMS_SUCCESSFUL)
979 if (status[STATUS_3] != RTEMS_SUCCESSFUL)
980 {
980 {
981 PRINTF1("in restart_science_task *** CWF3 ERR %d\n", status[STATUS_3])
981 PRINTF1("in restart_science_task *** CWF3 ERR %d\n", status[STATUS_3])
982 }
982 }
983
983
984 status[STATUS_4] = rtems_task_restart( Task_id[TASKID_CWF2],1 );
984 status[STATUS_4] = rtems_task_restart( Task_id[TASKID_CWF2],1 );
985 if (status[STATUS_4] != RTEMS_SUCCESSFUL)
985 if (status[STATUS_4] != RTEMS_SUCCESSFUL)
986 {
986 {
987 PRINTF1("in restart_science_task *** CWF2 ERR %d\n", status[STATUS_4])
987 PRINTF1("in restart_science_task *** CWF2 ERR %d\n", status[STATUS_4])
988 }
988 }
989
989
990 status[STATUS_5] = rtems_task_restart( Task_id[TASKID_CWF1],1 );
990 status[STATUS_5] = rtems_task_restart( Task_id[TASKID_CWF1],1 );
991 if (status[STATUS_5] != RTEMS_SUCCESSFUL)
991 if (status[STATUS_5] != RTEMS_SUCCESSFUL)
992 {
992 {
993 PRINTF1("in restart_science_task *** CWF1 ERR %d\n", status[STATUS_5])
993 PRINTF1("in restart_science_task *** CWF1 ERR %d\n", status[STATUS_5])
994 }
994 }
995
995
996 status[STATUS_6] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
996 status[STATUS_6] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
997 if (status[STATUS_6] != RTEMS_SUCCESSFUL)
997 if (status[STATUS_6] != RTEMS_SUCCESSFUL)
998 {
998 {
999 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[STATUS_6])
999 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[STATUS_6])
1000 }
1000 }
1001
1001
1002 status[STATUS_7] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
1002 status[STATUS_7] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
1003 if (status[STATUS_7] != RTEMS_SUCCESSFUL)
1003 if (status[STATUS_7] != RTEMS_SUCCESSFUL)
1004 {
1004 {
1005 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[STATUS_7])
1005 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[STATUS_7])
1006 }
1006 }
1007
1007
1008 status[STATUS_8] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
1008 status[STATUS_8] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
1009 if (status[STATUS_8] != RTEMS_SUCCESSFUL)
1009 if (status[STATUS_8] != RTEMS_SUCCESSFUL)
1010 {
1010 {
1011 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[STATUS_8])
1011 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[STATUS_8])
1012 }
1012 }
1013
1013
1014 status[STATUS_9] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
1014 status[STATUS_9] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
1015 if (status[STATUS_9] != RTEMS_SUCCESSFUL)
1015 if (status[STATUS_9] != RTEMS_SUCCESSFUL)
1016 {
1016 {
1017 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[STATUS_9])
1017 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[STATUS_9])
1018 }
1018 }
1019
1019
1020 if ( (status[STATUS_0] != RTEMS_SUCCESSFUL) || (status[STATUS_1] != RTEMS_SUCCESSFUL) ||
1020 if ( (status[STATUS_0] != RTEMS_SUCCESSFUL) || (status[STATUS_1] != RTEMS_SUCCESSFUL) ||
1021 (status[STATUS_2] != RTEMS_SUCCESSFUL) || (status[STATUS_3] != RTEMS_SUCCESSFUL) ||
1021 (status[STATUS_2] != RTEMS_SUCCESSFUL) || (status[STATUS_3] != RTEMS_SUCCESSFUL) ||
1022 (status[STATUS_4] != RTEMS_SUCCESSFUL) || (status[STATUS_5] != RTEMS_SUCCESSFUL) ||
1022 (status[STATUS_4] != RTEMS_SUCCESSFUL) || (status[STATUS_5] != RTEMS_SUCCESSFUL) ||
1023 (status[STATUS_6] != RTEMS_SUCCESSFUL) || (status[STATUS_7] != RTEMS_SUCCESSFUL) ||
1023 (status[STATUS_6] != RTEMS_SUCCESSFUL) || (status[STATUS_7] != RTEMS_SUCCESSFUL) ||
1024 (status[STATUS_8] != RTEMS_SUCCESSFUL) || (status[STATUS_9] != RTEMS_SUCCESSFUL) )
1024 (status[STATUS_8] != RTEMS_SUCCESSFUL) || (status[STATUS_9] != RTEMS_SUCCESSFUL) )
1025 {
1025 {
1026 ret = RTEMS_UNSATISFIED;
1026 ret = RTEMS_UNSATISFIED;
1027 }
1027 }
1028
1028
1029 return ret;
1029 return ret;
1030 }
1030 }
1031
1031
1032 int restart_asm_tasks( unsigned char lfrRequestedMode )
1032 int restart_asm_tasks( unsigned char lfrRequestedMode )
1033 {
1033 {
1034 /** This function is used to restart average spectral matrices tasks.
1034 /** This function is used to restart average spectral matrices tasks.
1035 *
1035 *
1036 * @return RTEMS directive status codes:
1036 * @return RTEMS directive status codes:
1037 * - RTEMS_SUCCESSFUL - task restarted successfully
1037 * - RTEMS_SUCCESSFUL - task restarted successfully
1038 * - RTEMS_INVALID_ID - task id invalid
1038 * - RTEMS_INVALID_ID - task id invalid
1039 * - RTEMS_INCORRECT_STATE - task never started
1039 * - RTEMS_INCORRECT_STATE - task never started
1040 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
1040 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
1041 *
1041 *
1042 * ASM tasks are AVF0, PRC0, AVF1, PRC1, AVF2 and PRC2
1042 * ASM tasks are AVF0, PRC0, AVF1, PRC1, AVF2 and PRC2
1043 *
1043 *
1044 */
1044 */
1045
1045
1046 rtems_status_code status[NB_ASM_TASKS];
1046 rtems_status_code status[NB_ASM_TASKS];
1047 rtems_status_code ret;
1047 rtems_status_code ret;
1048
1048
1049 ret = RTEMS_SUCCESSFUL;
1049 ret = RTEMS_SUCCESSFUL;
1050
1050
1051 status[STATUS_0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
1051 status[STATUS_0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
1052 if (status[STATUS_0] != RTEMS_SUCCESSFUL)
1052 if (status[STATUS_0] != RTEMS_SUCCESSFUL)
1053 {
1053 {
1054 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[STATUS_0])
1054 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[STATUS_0])
1055 }
1055 }
1056
1056
1057 status[STATUS_1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
1057 status[STATUS_1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
1058 if (status[STATUS_1] != RTEMS_SUCCESSFUL)
1058 if (status[STATUS_1] != RTEMS_SUCCESSFUL)
1059 {
1059 {
1060 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[STATUS_1])
1060 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[STATUS_1])
1061 }
1061 }
1062
1062
1063 status[STATUS_2] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
1063 status[STATUS_2] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
1064 if (status[STATUS_2] != RTEMS_SUCCESSFUL)
1064 if (status[STATUS_2] != RTEMS_SUCCESSFUL)
1065 {
1065 {
1066 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[STATUS_2])
1066 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[STATUS_2])
1067 }
1067 }
1068
1068
1069 status[STATUS_3] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
1069 status[STATUS_3] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
1070 if (status[STATUS_3] != RTEMS_SUCCESSFUL)
1070 if (status[STATUS_3] != RTEMS_SUCCESSFUL)
1071 {
1071 {
1072 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[STATUS_3])
1072 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[STATUS_3])
1073 }
1073 }
1074
1074
1075 status[STATUS_4] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
1075 status[STATUS_4] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
1076 if (status[STATUS_4] != RTEMS_SUCCESSFUL)
1076 if (status[STATUS_4] != RTEMS_SUCCESSFUL)
1077 {
1077 {
1078 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[STATUS_4])
1078 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[STATUS_4])
1079 }
1079 }
1080
1080
1081 status[STATUS_5] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
1081 status[STATUS_5] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
1082 if (status[STATUS_5] != RTEMS_SUCCESSFUL)
1082 if (status[STATUS_5] != RTEMS_SUCCESSFUL)
1083 {
1083 {
1084 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[STATUS_5])
1084 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[STATUS_5])
1085 }
1085 }
1086
1086
1087 if ( (status[STATUS_0] != RTEMS_SUCCESSFUL) || (status[STATUS_1] != RTEMS_SUCCESSFUL) ||
1087 if ( (status[STATUS_0] != RTEMS_SUCCESSFUL) || (status[STATUS_1] != RTEMS_SUCCESSFUL) ||
1088 (status[STATUS_2] != RTEMS_SUCCESSFUL) || (status[STATUS_3] != RTEMS_SUCCESSFUL) ||
1088 (status[STATUS_2] != RTEMS_SUCCESSFUL) || (status[STATUS_3] != RTEMS_SUCCESSFUL) ||
1089 (status[STATUS_4] != RTEMS_SUCCESSFUL) || (status[STATUS_5] != RTEMS_SUCCESSFUL) )
1089 (status[STATUS_4] != RTEMS_SUCCESSFUL) || (status[STATUS_5] != RTEMS_SUCCESSFUL) )
1090 {
1090 {
1091 ret = RTEMS_UNSATISFIED;
1091 ret = RTEMS_UNSATISFIED;
1092 }
1092 }
1093
1093
1094 return ret;
1094 return ret;
1095 }
1095 }
1096
1096
1097 int suspend_science_tasks( void )
1097 int suspend_science_tasks( void )
1098 {
1098 {
1099 /** This function suspends the science tasks.
1099 /** This function suspends the science tasks.
1100 *
1100 *
1101 * @return RTEMS directive status codes:
1101 * @return RTEMS directive status codes:
1102 * - RTEMS_SUCCESSFUL - task restarted successfully
1102 * - RTEMS_SUCCESSFUL - task restarted successfully
1103 * - RTEMS_INVALID_ID - task id invalid
1103 * - RTEMS_INVALID_ID - task id invalid
1104 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1104 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1105 *
1105 *
1106 */
1106 */
1107
1107
1108 rtems_status_code status;
1108 rtems_status_code status;
1109
1109
1110 PRINTF("in suspend_science_tasks\n")
1110 PRINTF("in suspend_science_tasks\n")
1111
1111
1112 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1112 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1113 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1113 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1114 {
1114 {
1115 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1115 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1116 }
1116 }
1117 else
1117 else
1118 {
1118 {
1119 status = RTEMS_SUCCESSFUL;
1119 status = RTEMS_SUCCESSFUL;
1120 }
1120 }
1121 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1121 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1122 {
1122 {
1123 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1123 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1124 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1124 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1125 {
1125 {
1126 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1126 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1127 }
1127 }
1128 else
1128 else
1129 {
1129 {
1130 status = RTEMS_SUCCESSFUL;
1130 status = RTEMS_SUCCESSFUL;
1131 }
1131 }
1132 }
1132 }
1133 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1133 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1134 {
1134 {
1135 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1135 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1136 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1136 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1137 {
1137 {
1138 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1138 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1139 }
1139 }
1140 else
1140 else
1141 {
1141 {
1142 status = RTEMS_SUCCESSFUL;
1142 status = RTEMS_SUCCESSFUL;
1143 }
1143 }
1144 }
1144 }
1145 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1145 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1146 {
1146 {
1147 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1147 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1148 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1148 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1149 {
1149 {
1150 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1150 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1151 }
1151 }
1152 else
1152 else
1153 {
1153 {
1154 status = RTEMS_SUCCESSFUL;
1154 status = RTEMS_SUCCESSFUL;
1155 }
1155 }
1156 }
1156 }
1157 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1157 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1158 {
1158 {
1159 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1159 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1160 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1160 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1161 {
1161 {
1162 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1162 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1163 }
1163 }
1164 else
1164 else
1165 {
1165 {
1166 status = RTEMS_SUCCESSFUL;
1166 status = RTEMS_SUCCESSFUL;
1167 }
1167 }
1168 }
1168 }
1169 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1169 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1170 {
1170 {
1171 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1171 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1172 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1172 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1173 {
1173 {
1174 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1174 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1175 }
1175 }
1176 else
1176 else
1177 {
1177 {
1178 status = RTEMS_SUCCESSFUL;
1178 status = RTEMS_SUCCESSFUL;
1179 }
1179 }
1180 }
1180 }
1181 if (status == RTEMS_SUCCESSFUL) // suspend WFRM
1181 if (status == RTEMS_SUCCESSFUL) // suspend WFRM
1182 {
1182 {
1183 status = rtems_task_suspend( Task_id[TASKID_WFRM] );
1183 status = rtems_task_suspend( Task_id[TASKID_WFRM] );
1184 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1184 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1185 {
1185 {
1186 PRINTF1("in suspend_science_task *** WFRM ERR %d\n", status)
1186 PRINTF1("in suspend_science_task *** WFRM ERR %d\n", status)
1187 }
1187 }
1188 else
1188 else
1189 {
1189 {
1190 status = RTEMS_SUCCESSFUL;
1190 status = RTEMS_SUCCESSFUL;
1191 }
1191 }
1192 }
1192 }
1193 if (status == RTEMS_SUCCESSFUL) // suspend CWF3
1193 if (status == RTEMS_SUCCESSFUL) // suspend CWF3
1194 {
1194 {
1195 status = rtems_task_suspend( Task_id[TASKID_CWF3] );
1195 status = rtems_task_suspend( Task_id[TASKID_CWF3] );
1196 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1196 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1197 {
1197 {
1198 PRINTF1("in suspend_science_task *** CWF3 ERR %d\n", status)
1198 PRINTF1("in suspend_science_task *** CWF3 ERR %d\n", status)
1199 }
1199 }
1200 else
1200 else
1201 {
1201 {
1202 status = RTEMS_SUCCESSFUL;
1202 status = RTEMS_SUCCESSFUL;
1203 }
1203 }
1204 }
1204 }
1205 if (status == RTEMS_SUCCESSFUL) // suspend CWF2
1205 if (status == RTEMS_SUCCESSFUL) // suspend CWF2
1206 {
1206 {
1207 status = rtems_task_suspend( Task_id[TASKID_CWF2] );
1207 status = rtems_task_suspend( Task_id[TASKID_CWF2] );
1208 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1208 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1209 {
1209 {
1210 PRINTF1("in suspend_science_task *** CWF2 ERR %d\n", status)
1210 PRINTF1("in suspend_science_task *** CWF2 ERR %d\n", status)
1211 }
1211 }
1212 else
1212 else
1213 {
1213 {
1214 status = RTEMS_SUCCESSFUL;
1214 status = RTEMS_SUCCESSFUL;
1215 }
1215 }
1216 }
1216 }
1217 if (status == RTEMS_SUCCESSFUL) // suspend CWF1
1217 if (status == RTEMS_SUCCESSFUL) // suspend CWF1
1218 {
1218 {
1219 status = rtems_task_suspend( Task_id[TASKID_CWF1] );
1219 status = rtems_task_suspend( Task_id[TASKID_CWF1] );
1220 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1220 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1221 {
1221 {
1222 PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status)
1222 PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status)
1223 }
1223 }
1224 else
1224 else
1225 {
1225 {
1226 status = RTEMS_SUCCESSFUL;
1226 status = RTEMS_SUCCESSFUL;
1227 }
1227 }
1228 }
1228 }
1229
1229
1230 return status;
1230 return status;
1231 }
1231 }
1232
1232
1233 int suspend_asm_tasks( void )
1233 int suspend_asm_tasks( void )
1234 {
1234 {
1235 /** This function suspends the science tasks.
1235 /** This function suspends the science tasks.
1236 *
1236 *
1237 * @return RTEMS directive status codes:
1237 * @return RTEMS directive status codes:
1238 * - RTEMS_SUCCESSFUL - task restarted successfully
1238 * - RTEMS_SUCCESSFUL - task restarted successfully
1239 * - RTEMS_INVALID_ID - task id invalid
1239 * - RTEMS_INVALID_ID - task id invalid
1240 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1240 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1241 *
1241 *
1242 */
1242 */
1243
1243
1244 rtems_status_code status;
1244 rtems_status_code status;
1245
1245
1246 PRINTF("in suspend_science_tasks\n")
1246 PRINTF("in suspend_science_tasks\n")
1247
1247
1248 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1248 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1249 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1249 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1250 {
1250 {
1251 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1251 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1252 }
1252 }
1253 else
1253 else
1254 {
1254 {
1255 status = RTEMS_SUCCESSFUL;
1255 status = RTEMS_SUCCESSFUL;
1256 }
1256 }
1257
1257
1258 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1258 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1259 {
1259 {
1260 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1260 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1261 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1261 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1262 {
1262 {
1263 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1263 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1264 }
1264 }
1265 else
1265 else
1266 {
1266 {
1267 status = RTEMS_SUCCESSFUL;
1267 status = RTEMS_SUCCESSFUL;
1268 }
1268 }
1269 }
1269 }
1270
1270
1271 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1271 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1272 {
1272 {
1273 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1273 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1274 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1274 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1275 {
1275 {
1276 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1276 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1277 }
1277 }
1278 else
1278 else
1279 {
1279 {
1280 status = RTEMS_SUCCESSFUL;
1280 status = RTEMS_SUCCESSFUL;
1281 }
1281 }
1282 }
1282 }
1283
1283
1284 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1284 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1285 {
1285 {
1286 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1286 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1287 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1287 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1288 {
1288 {
1289 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1289 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1290 }
1290 }
1291 else
1291 else
1292 {
1292 {
1293 status = RTEMS_SUCCESSFUL;
1293 status = RTEMS_SUCCESSFUL;
1294 }
1294 }
1295 }
1295 }
1296
1296
1297 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1297 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1298 {
1298 {
1299 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1299 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1300 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1300 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1301 {
1301 {
1302 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1302 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1303 }
1303 }
1304 else
1304 else
1305 {
1305 {
1306 status = RTEMS_SUCCESSFUL;
1306 status = RTEMS_SUCCESSFUL;
1307 }
1307 }
1308 }
1308 }
1309
1309
1310 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1310 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1311 {
1311 {
1312 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1312 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1313 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1313 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1314 {
1314 {
1315 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1315 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1316 }
1316 }
1317 else
1317 else
1318 {
1318 {
1319 status = RTEMS_SUCCESSFUL;
1319 status = RTEMS_SUCCESSFUL;
1320 }
1320 }
1321 }
1321 }
1322
1322
1323 return status;
1323 return status;
1324 }
1324 }
1325
1325
1326 void launch_waveform_picker( unsigned char mode, unsigned int transitionCoarseTime )
1326 void launch_waveform_picker( unsigned char mode, unsigned int transitionCoarseTime )
1327 {
1327 {
1328
1328
1329 WFP_reset_current_ring_nodes();
1329 WFP_reset_current_ring_nodes();
1330
1330
1331 reset_waveform_picker_regs();
1331 reset_waveform_picker_regs();
1332
1332
1333 set_wfp_burst_enable_register( mode );
1333 set_wfp_burst_enable_register( mode );
1334
1334
1335 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER );
1335 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER );
1336 LEON_Unmask_interrupt( IRQ_WAVEFORM_PICKER );
1336 LEON_Unmask_interrupt( IRQ_WAVEFORM_PICKER );
1337
1337
1338 if (transitionCoarseTime == 0)
1338 if (transitionCoarseTime == 0)
1339 {
1339 {
1340 // instant transition means transition on the next valid date
1340 // instant transition means transition on the next valid date
1341 // this is mandatory to have a good snapshot period and a good correction of the snapshot period
1341 // this is mandatory to have a good snapshot period and a good correction of the snapshot period
1342 waveform_picker_regs->start_date = time_management_regs->coarse_time + 1;
1342 waveform_picker_regs->start_date = time_management_regs->coarse_time + 1;
1343 }
1343 }
1344 else
1344 else
1345 {
1345 {
1346 waveform_picker_regs->start_date = transitionCoarseTime;
1346 waveform_picker_regs->start_date = transitionCoarseTime;
1347 }
1347 }
1348
1348
1349 update_last_valid_transition_date(waveform_picker_regs->start_date);
1349 update_last_valid_transition_date(waveform_picker_regs->start_date);
1350
1350
1351 }
1351 }
1352
1352
1353 void launch_spectral_matrix( void )
1353 void launch_spectral_matrix( void )
1354 {
1354 {
1355 SM_reset_current_ring_nodes();
1355 SM_reset_current_ring_nodes();
1356
1356
1357 reset_spectral_matrix_regs();
1357 reset_spectral_matrix_regs();
1358
1358
1359 reset_nb_sm();
1359 reset_nb_sm();
1360
1360
1361 set_sm_irq_onNewMatrix( 1 );
1361 set_sm_irq_onNewMatrix( 1 );
1362
1362
1363 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX );
1363 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX );
1364 LEON_Unmask_interrupt( IRQ_SPECTRAL_MATRIX );
1364 LEON_Unmask_interrupt( IRQ_SPECTRAL_MATRIX );
1365
1365
1366 }
1366 }
1367
1367
1368 void set_sm_irq_onNewMatrix( unsigned char value )
1368 void set_sm_irq_onNewMatrix( unsigned char value )
1369 {
1369 {
1370 if (value == 1)
1370 if (value == 1)
1371 {
1371 {
1372 spectral_matrix_regs->config = spectral_matrix_regs->config | BIT_IRQ_ON_NEW_MATRIX;
1372 spectral_matrix_regs->config = spectral_matrix_regs->config | BIT_IRQ_ON_NEW_MATRIX;
1373 }
1373 }
1374 else
1374 else
1375 {
1375 {
1376 spectral_matrix_regs->config = spectral_matrix_regs->config & MASK_IRQ_ON_NEW_MATRIX; // 1110
1376 spectral_matrix_regs->config = spectral_matrix_regs->config & MASK_IRQ_ON_NEW_MATRIX; // 1110
1377 }
1377 }
1378 }
1378 }
1379
1379
1380 void set_sm_irq_onError( unsigned char value )
1380 void set_sm_irq_onError( unsigned char value )
1381 {
1381 {
1382 if (value == 1)
1382 if (value == 1)
1383 {
1383 {
1384 spectral_matrix_regs->config = spectral_matrix_regs->config | BIT_IRQ_ON_ERROR;
1384 spectral_matrix_regs->config = spectral_matrix_regs->config | BIT_IRQ_ON_ERROR;
1385 }
1385 }
1386 else
1386 else
1387 {
1387 {
1388 spectral_matrix_regs->config = spectral_matrix_regs->config & MASK_IRQ_ON_ERROR; // 1101
1388 spectral_matrix_regs->config = spectral_matrix_regs->config & MASK_IRQ_ON_ERROR; // 1101
1389 }
1389 }
1390 }
1390 }
1391
1391
1392 //*****************************
1392 //*****************************
1393 // CONFIGURE CALIBRATION SIGNAL
1393 // CONFIGURE CALIBRATION SIGNAL
1394 void setCalibrationPrescaler( unsigned int prescaler )
1394 void setCalibrationPrescaler( unsigned int prescaler )
1395 {
1395 {
1396 // prescaling of the master clock (25 MHz)
1396 // prescaling of the master clock (25 MHz)
1397 // master clock is divided by 2^prescaler
1397 // master clock is divided by 2^prescaler
1398 time_management_regs->calPrescaler = prescaler;
1398 time_management_regs->calPrescaler = prescaler;
1399 }
1399 }
1400
1400
1401 void setCalibrationDivisor( unsigned int divisionFactor )
1401 void setCalibrationDivisor( unsigned int divisionFactor )
1402 {
1402 {
1403 // division of the prescaled clock by the division factor
1403 // division of the prescaled clock by the division factor
1404 time_management_regs->calDivisor = divisionFactor;
1404 time_management_regs->calDivisor = divisionFactor;
1405 }
1405 }
1406
1406
1407 void setCalibrationData( void )
1407 void setCalibrationData( void )
1408 {
1408 {
1409 /** This function is used to store the values used to drive the DAC in order to generate the SCM calibration signal
1409 /** This function is used to store the values used to drive the DAC in order to generate the SCM calibration signal
1410 *
1410 *
1411 * @param void
1411 * @param void
1412 *
1412 *
1413 * @return void
1413 * @return void
1414 *
1414 *
1415 */
1415 */
1416
1416
1417 unsigned int k;
1417 unsigned int k;
1418 unsigned short data;
1418 unsigned short data;
1419 float val;
1419 float val;
1420 float Ts;
1420 float Ts;
1421
1421
1422 time_management_regs->calDataPtr = INIT_CHAR;
1422 time_management_regs->calDataPtr = INIT_CHAR;
1423
1423
1424 Ts = 1 / CAL_FS;
1424 Ts = 1 / CAL_FS;
1425
1425
1426 // build the signal for the SCM calibration
1426 // build the signal for the SCM calibration
1427 for (k = 0; k < CAL_NB_PTS; k++)
1427 for (k = 0; k < CAL_NB_PTS; k++)
1428 {
1428 {
1429 val = CAL_A0 * sin( CAL_W0 * k * Ts )
1429 val = CAL_A0 * sin( CAL_W0 * k * Ts )
1430 + CAL_A1 * sin( CAL_W1 * k * Ts );
1430 + CAL_A1 * sin( CAL_W1 * k * Ts );
1431 data = (unsigned short) ((val * CAL_SCALE_FACTOR) + CONST_2048);
1431 data = (unsigned short) ((val * CAL_SCALE_FACTOR) + CONST_2048);
1432 time_management_regs->calData = data & CAL_DATA_MASK;
1432 time_management_regs->calData = data & CAL_DATA_MASK;
1433 }
1433 }
1434 }
1434 }
1435
1435
1436 #ifdef ENABLE_DEAD_CODE
1436 void setCalibrationDataInterleaved( void )
1437 void setCalibrationDataInterleaved( void )
1437 {
1438 {
1438 /** This function is used to store the values used to drive the DAC in order to generate the SCM calibration signal
1439 /** This function is used to store the values used to drive the DAC in order to generate the SCM calibration signal
1439 *
1440 *
1440 * @param void
1441 * @param void
1441 *
1442 *
1442 * @return void
1443 * @return void
1443 *
1444 *
1444 * In interleaved mode, one can store more values than in normal mode.
1445 * In interleaved mode, one can store more values than in normal mode.
1445 * The data are stored in bunch of 18 bits, 12 bits from one sample and 6 bits from another sample.
1446 * The data are stored in bunch of 18 bits, 12 bits from one sample and 6 bits from another sample.
1446 * T store 3 values, one need two write operations.
1447 * T store 3 values, one need two write operations.
1447 * s1 [ b11 b10 b9 b8 b7 b6 ] s0 [ b11 b10 b9 b8 b7 b6 b5 b3 b2 b1 b0 ]
1448 * s1 [ b11 b10 b9 b8 b7 b6 ] s0 [ b11 b10 b9 b8 b7 b6 b5 b3 b2 b1 b0 ]
1448 * s1 [ b5 b4 b3 b2 b1 b0 ] s2 [ b11 b10 b9 b8 b7 b6 b5 b3 b2 b1 b0 ]
1449 * s1 [ b5 b4 b3 b2 b1 b0 ] s2 [ b11 b10 b9 b8 b7 b6 b5 b3 b2 b1 b0 ]
1449 *
1450 *
1450 */
1451 */
1451
1452
1452 unsigned int k;
1453 unsigned int k;
1453 float val;
1454 float val;
1454 float Ts;
1455 float Ts;
1455 unsigned short data[CAL_NB_PTS_INTER];
1456 unsigned short data[CAL_NB_PTS_INTER];
1456 unsigned char *dataPtr;
1457 unsigned char *dataPtr;
1457
1458
1458 Ts = 1 / CAL_FS_INTER;
1459 Ts = 1 / CAL_FS_INTER;
1459
1460
1460 time_management_regs->calDataPtr = INIT_CHAR;
1461 time_management_regs->calDataPtr = INIT_CHAR;
1461
1462
1462 // build the signal for the SCM calibration
1463 // build the signal for the SCM calibration
1463 for (k=0; k<CAL_NB_PTS_INTER; k++)
1464 for (k=0; k<CAL_NB_PTS_INTER; k++)
1464 {
1465 {
1465 val = sin( 2 * pi * CAL_F0 * k * Ts )
1466 val = sin( 2 * pi * CAL_F0 * k * Ts )
1466 + sin( 2 * pi * CAL_F1 * k * Ts );
1467 + sin( 2 * pi * CAL_F1 * k * Ts );
1467 data[k] = (unsigned short) ((val * CONST_512) + CONST_2048);
1468 data[k] = (unsigned short) ((val * CONST_512) + CONST_2048);
1468 }
1469 }
1469
1470
1470 // write the signal in interleaved mode
1471 // write the signal in interleaved mode
1471 for (k=0; k < STEPS_FOR_STORAGE_INTER; k++)
1472 for (k=0; k < STEPS_FOR_STORAGE_INTER; k++)
1472 {
1473 {
1473 dataPtr = (unsigned char*) &data[ (k * BYTES_FOR_2_SAMPLES) + 2 ];
1474 dataPtr = (unsigned char*) &data[ (k * BYTES_FOR_2_SAMPLES) + 2 ];
1474 time_management_regs->calData = ( data[ k * BYTES_FOR_2_SAMPLES ] & CAL_DATA_MASK )
1475 time_management_regs->calData = ( data[ k * BYTES_FOR_2_SAMPLES ] & CAL_DATA_MASK )
1475 + ( (dataPtr[0] & CAL_DATA_MASK_INTER) << CAL_DATA_SHIFT_INTER);
1476 + ( (dataPtr[0] & CAL_DATA_MASK_INTER) << CAL_DATA_SHIFT_INTER);
1476 time_management_regs->calData = ( data[(k * BYTES_FOR_2_SAMPLES) + 1] & CAL_DATA_MASK )
1477 time_management_regs->calData = ( data[(k * BYTES_FOR_2_SAMPLES) + 1] & CAL_DATA_MASK )
1477 + ( (dataPtr[1] & CAL_DATA_MASK_INTER) << CAL_DATA_SHIFT_INTER);
1478 + ( (dataPtr[1] & CAL_DATA_MASK_INTER) << CAL_DATA_SHIFT_INTER);
1478 }
1479 }
1479 }
1480 }
1481 #endif
1480
1482
1481 void setCalibrationReload( bool state)
1483 void setCalibrationReload( bool state)
1482 {
1484 {
1483 if (state == true)
1485 if (state == true)
1484 {
1486 {
1485 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_CAL_RELOAD; // [0001 0000]
1487 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_CAL_RELOAD; // [0001 0000]
1486 }
1488 }
1487 else
1489 else
1488 {
1490 {
1489 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_CAL_RELOAD; // [1110 1111]
1491 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_CAL_RELOAD; // [1110 1111]
1490 }
1492 }
1491 }
1493 }
1492
1494
1493 void setCalibrationEnable( bool state )
1495 void setCalibrationEnable( bool state )
1494 {
1496 {
1495 // this bit drives the multiplexer
1497 // this bit drives the multiplexer
1496 if (state == true)
1498 if (state == true)
1497 {
1499 {
1498 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_CAL_ENABLE; // [0100 0000]
1500 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_CAL_ENABLE; // [0100 0000]
1499 }
1501 }
1500 else
1502 else
1501 {
1503 {
1502 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_CAL_ENABLE; // [1011 1111]
1504 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_CAL_ENABLE; // [1011 1111]
1503 }
1505 }
1504 }
1506 }
1505
1507
1508 #ifdef ENABLE_DEAD_CODE
1506 void setCalibrationInterleaved( bool state )
1509 void setCalibrationInterleaved( bool state )
1507 {
1510 {
1508 // this bit drives the multiplexer
1511 // this bit drives the multiplexer
1509 if (state == true)
1512 if (state == true)
1510 {
1513 {
1511 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_SET_INTERLEAVED; // [0010 0000]
1514 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_SET_INTERLEAVED; // [0010 0000]
1512 }
1515 }
1513 else
1516 else
1514 {
1517 {
1515 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_SET_INTERLEAVED; // [1101 1111]
1518 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_SET_INTERLEAVED; // [1101 1111]
1516 }
1519 }
1517 }
1520 }
1521 #endif
1518
1522
1519 void setCalibration( bool state )
1523 void setCalibration( bool state )
1520 {
1524 {
1521 if (state == true)
1525 if (state == true)
1522 {
1526 {
1523 setCalibrationEnable( true );
1527 setCalibrationEnable( true );
1524 setCalibrationReload( false );
1528 setCalibrationReload( false );
1525 set_hk_lfr_calib_enable( true );
1529 set_hk_lfr_calib_enable( true );
1526 }
1530 }
1527 else
1531 else
1528 {
1532 {
1529 setCalibrationEnable( false );
1533 setCalibrationEnable( false );
1530 setCalibrationReload( true );
1534 setCalibrationReload( true );
1531 set_hk_lfr_calib_enable( false );
1535 set_hk_lfr_calib_enable( false );
1532 }
1536 }
1533 }
1537 }
1534
1538
1535 void configureCalibration( bool interleaved )
1539 void configureCalibration( bool interleaved )
1536 {
1540 {
1537 setCalibration( false );
1541 setCalibration( false );
1542 #ifdef ENABLE_DEAD_CODE
1538 if ( interleaved == true )
1543 if ( interleaved == true )
1539 {
1544 {
1540 setCalibrationInterleaved( true );
1545 setCalibrationInterleaved( true );
1541 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1546 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1542 setCalibrationDivisor( CAL_F_DIVISOR_INTER ); // => 240 384
1547 setCalibrationDivisor( CAL_F_DIVISOR_INTER ); // => 240 384
1543 setCalibrationDataInterleaved();
1548 setCalibrationDataInterleaved();
1544 }
1549 }
1545 else
1550 else
1551 #endif
1546 {
1552 {
1547 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1553 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1548 setCalibrationDivisor( CAL_F_DIVISOR ); // => 160 256 (39 - 1)
1554 setCalibrationDivisor( CAL_F_DIVISOR ); // => 160 256 (39 - 1)
1549 setCalibrationData();
1555 setCalibrationData();
1550 }
1556 }
1551 }
1557 }
1552
1558
1553 //****************
1559 //****************
1554 // CLOSING ACTIONS
1560 // CLOSING ACTIONS
1555 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )
1561 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )
1556 {
1562 {
1557 /** This function is used to update the HK packets statistics after a successful TC execution.
1563 /** This function is used to update the HK packets statistics after a successful TC execution.
1558 *
1564 *
1559 * @param TC points to the TC being processed
1565 * @param TC points to the TC being processed
1560 * @param time is the time used to date the TC execution
1566 * @param time is the time used to date the TC execution
1561 *
1567 *
1562 */
1568 */
1563
1569
1564 unsigned int val;
1570 unsigned int val;
1565
1571
1566 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
1572 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
1567 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
1573 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
1568 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = INIT_CHAR;
1574 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = INIT_CHAR;
1569 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
1575 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
1570 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = INIT_CHAR;
1576 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = INIT_CHAR;
1571 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
1577 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
1572 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_0] = time[BYTE_0];
1578 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_0] = time[BYTE_0];
1573 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_1] = time[BYTE_1];
1579 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_1] = time[BYTE_1];
1574 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_2] = time[BYTE_2];
1580 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_2] = time[BYTE_2];
1575 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_3] = time[BYTE_3];
1581 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_3] = time[BYTE_3];
1576 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_4] = time[BYTE_4];
1582 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_4] = time[BYTE_4];
1577 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_5] = time[BYTE_5];
1583 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_5] = time[BYTE_5];
1578
1584
1579 val = (housekeeping_packet.hk_lfr_exe_tc_cnt[0] * CONST_256) + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
1585 val = (housekeeping_packet.hk_lfr_exe_tc_cnt[0] * CONST_256) + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
1580 val++;
1586 val++;
1581 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
1587 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
1582 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
1588 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
1583 }
1589 }
1584
1590
1585 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC, unsigned char * time )
1591 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC, unsigned char * time )
1586 {
1592 {
1587 /** This function is used to update the HK packets statistics after a TC rejection.
1593 /** This function is used to update the HK packets statistics after a TC rejection.
1588 *
1594 *
1589 * @param TC points to the TC being processed
1595 * @param TC points to the TC being processed
1590 * @param time is the time used to date the TC rejection
1596 * @param time is the time used to date the TC rejection
1591 *
1597 *
1592 */
1598 */
1593
1599
1594 unsigned int val;
1600 unsigned int val;
1595
1601
1596 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
1602 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
1597 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
1603 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
1598 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = INIT_CHAR;
1604 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = INIT_CHAR;
1599 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
1605 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
1600 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = INIT_CHAR;
1606 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = INIT_CHAR;
1601 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
1607 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
1602 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_0] = time[BYTE_0];
1608 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_0] = time[BYTE_0];
1603 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_1] = time[BYTE_1];
1609 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_1] = time[BYTE_1];
1604 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_2] = time[BYTE_2];
1610 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_2] = time[BYTE_2];
1605 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_3] = time[BYTE_3];
1611 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_3] = time[BYTE_3];
1606 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_4] = time[BYTE_4];
1612 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_4] = time[BYTE_4];
1607 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_5] = time[BYTE_5];
1613 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_5] = time[BYTE_5];
1608
1614
1609 val = (housekeeping_packet.hk_lfr_rej_tc_cnt[0] * CONST_256) + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
1615 val = (housekeeping_packet.hk_lfr_rej_tc_cnt[0] * CONST_256) + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
1610 val++;
1616 val++;
1611 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
1617 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
1612 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
1618 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
1613 }
1619 }
1614
1620
1615 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
1621 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
1616 {
1622 {
1617 /** This function is the last step of the TC execution workflow.
1623 /** This function is the last step of the TC execution workflow.
1618 *
1624 *
1619 * @param TC points to the TC being processed
1625 * @param TC points to the TC being processed
1620 * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
1626 * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
1621 * @param queue_id is the id of the RTEMS message queue used to send TM packets
1627 * @param queue_id is the id of the RTEMS message queue used to send TM packets
1622 * @param time is the time used to date the TC execution
1628 * @param time is the time used to date the TC execution
1623 *
1629 *
1624 */
1630 */
1625
1631
1626 unsigned char requestedMode;
1632 unsigned char requestedMode;
1627
1633
1628 if (result == LFR_SUCCESSFUL)
1634 if (result == LFR_SUCCESSFUL)
1629 {
1635 {
1630 if ( !( (TC->serviceType==TC_TYPE_TIME) & (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
1636 if ( !( (TC->serviceType==TC_TYPE_TIME) & (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
1631 &
1637 &
1632 !( (TC->serviceType==TC_TYPE_GEN) & (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
1638 !( (TC->serviceType==TC_TYPE_GEN) & (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
1633 )
1639 )
1634 {
1640 {
1635 send_tm_lfr_tc_exe_success( TC, queue_id );
1641 send_tm_lfr_tc_exe_success( TC, queue_id );
1636 }
1642 }
1637 if ( (TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_ENTER) )
1643 if ( (TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_ENTER) )
1638 {
1644 {
1639 //**********************************
1645 //**********************************
1640 // UPDATE THE LFRMODE LOCAL VARIABLE
1646 // UPDATE THE LFRMODE LOCAL VARIABLE
1641 requestedMode = TC->dataAndCRC[1];
1647 requestedMode = TC->dataAndCRC[1];
1642 updateLFRCurrentMode( requestedMode );
1648 updateLFRCurrentMode( requestedMode );
1643 }
1649 }
1644 }
1650 }
1645 else if (result == LFR_EXE_ERROR)
1651 else if (result == LFR_EXE_ERROR)
1646 {
1652 {
1647 send_tm_lfr_tc_exe_error( TC, queue_id );
1653 send_tm_lfr_tc_exe_error( TC, queue_id );
1648 }
1654 }
1649 }
1655 }
1650
1656
1651 //***************************
1652 // Interrupt Service Routines
1653 rtems_isr commutation_isr1( rtems_vector_number vector )
1654 {
1655 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1656 PRINTF("In commutation_isr1 *** Error sending event to DUMB\n")
1657 }
1658 }
1659
1660 rtems_isr commutation_isr2( rtems_vector_number vector )
1661 {
1662 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1663 PRINTF("In commutation_isr2 *** Error sending event to DUMB\n")
1664 }
1665 }
1666
1667 //****************
1657 //****************
1668 // OTHER FUNCTIONS
1658 // OTHER FUNCTIONS
1669 void updateLFRCurrentMode( unsigned char requestedMode )
1659 void updateLFRCurrentMode( unsigned char requestedMode )
1670 {
1660 {
1671 /** This function updates the value of the global variable lfrCurrentMode.
1661 /** This function updates the value of the global variable lfrCurrentMode.
1672 *
1662 *
1673 * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
1663 * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
1674 *
1664 *
1675 */
1665 */
1676
1666
1677 // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet structure
1667 // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet structure
1678 housekeeping_packet.lfr_status_word[0] = (housekeeping_packet.lfr_status_word[0] & STATUS_WORD_LFR_MODE_MASK)
1668 housekeeping_packet.lfr_status_word[0] = (housekeeping_packet.lfr_status_word[0] & STATUS_WORD_LFR_MODE_MASK)
1679 + (unsigned char) ( requestedMode << STATUS_WORD_LFR_MODE_SHIFT );
1669 + (unsigned char) ( requestedMode << STATUS_WORD_LFR_MODE_SHIFT );
1680 lfrCurrentMode = requestedMode;
1670 lfrCurrentMode = requestedMode;
1681 }
1671 }
1682
1672
1683 void set_lfr_soft_reset( unsigned char value )
1673 void set_lfr_soft_reset( unsigned char value )
1684 {
1674 {
1685 if (value == 1)
1675 if (value == 1)
1686 {
1676 {
1687 time_management_regs->ctrl = time_management_regs->ctrl | BIT_SOFT_RESET; // [0100]
1677 time_management_regs->ctrl = time_management_regs->ctrl | BIT_SOFT_RESET; // [0100]
1688 }
1678 }
1689 else
1679 else
1690 {
1680 {
1691 time_management_regs->ctrl = time_management_regs->ctrl & MASK_SOFT_RESET; // [1011]
1681 time_management_regs->ctrl = time_management_regs->ctrl & MASK_SOFT_RESET; // [1011]
1692 }
1682 }
1693 }
1683 }
1694
1684
1695 void reset_lfr( void )
1685 void reset_lfr( void )
1696 {
1686 {
1697 set_lfr_soft_reset( 1 );
1687 set_lfr_soft_reset( 1 );
1698
1688
1699 set_lfr_soft_reset( 0 );
1689 set_lfr_soft_reset( 0 );
1700
1690
1701 set_hk_lfr_sc_potential_flag( true );
1691 set_hk_lfr_sc_potential_flag( true );
1702 }
1692 }
@@ -1,536 +1,538
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW),
2 -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW),
3 -- This file is a part of the LFR FSW
3 -- This file is a part of the LFR FSW
4 -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS
4 -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS
5 --
5 --
6 -- This program is free software; you can redistribute it and/or modify
6 -- This program is free software; you can redistribute it and/or modify
7 -- it under the terms of the GNU General Public License as published by
7 -- it under the terms of the GNU General Public License as published by
8 -- the Free Software Foundation; either version 2 of the License, or
8 -- the Free Software Foundation; either version 2 of the License, or
9 -- (at your option) any later version.
9 -- (at your option) any later version.
10 --
10 --
11 -- This program is distributed in the hope that it will be useful,
11 -- This program is distributed in the hope that it will be useful,
12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 -- GNU General Public License for more details.
14 -- GNU General Public License for more details.
15 --
15 --
16 -- You should have received a copy of the GNU General Public License
16 -- You should have received a copy of the GNU General Public License
17 -- along with this program; if not, write to the Free Software
17 -- along with this program; if not, write to the Free Software
18 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 -------------------------------------------------------------------------------*/
19 -------------------------------------------------------------------------------*/
20 /*-- Author : Paul Leroy
20 /*-- Author : Paul Leroy
21 -- Contact : Alexis Jeandet
21 -- Contact : Alexis Jeandet
22 -- Mail : alexis.jeandet@lpp.polytechnique.fr
22 -- Mail : alexis.jeandet@lpp.polytechnique.fr
23 ----------------------------------------------------------------------------*/
23 ----------------------------------------------------------------------------*/
24
24
25 /** Functions to send TM packets related to TC parsing and execution.
25 /** Functions to send TM packets related to TC parsing and execution.
26 *
26 *
27 * @file
27 * @file
28 * @author P. LEROY
28 * @author P. LEROY
29 *
29 *
30 * A group of functions to send appropriate TM packets after parsing and execution:
30 * A group of functions to send appropriate TM packets after parsing and execution:
31 * - TM_LFR_TC_EXE_SUCCESS
31 * - TM_LFR_TC_EXE_SUCCESS
32 * - TM_LFR_TC_EXE_INCONSISTENT
32 * - TM_LFR_TC_EXE_INCONSISTENT
33 * - TM_LFR_TC_EXE_NOT_EXECUTABLE
33 * - TM_LFR_TC_EXE_NOT_EXECUTABLE
34 * - TM_LFR_TC_EXE_NOT_IMPLEMENTED
34 * - TM_LFR_TC_EXE_NOT_IMPLEMENTED
35 * - TM_LFR_TC_EXE_ERROR
35 * - TM_LFR_TC_EXE_ERROR
36 * - TM_LFR_TC_EXE_CORRUPTED
36 * - TM_LFR_TC_EXE_CORRUPTED
37 *
37 *
38 */
38 */
39
39
40 #include "tm_lfr_tc_exe.h"
40 #include "tm_lfr_tc_exe.h"
41
41
42 int send_tm_lfr_tc_exe_success( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
42 int send_tm_lfr_tc_exe_success( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
43 {
43 {
44 /** This function sends a TM_LFR_TC_EXE_SUCCESS packet in the dedicated RTEMS message queue.
44 /** This function sends a TM_LFR_TC_EXE_SUCCESS packet in the dedicated RTEMS message queue.
45 *
45 *
46 * @param TC points to the TeleCommand packet that is being processed
46 * @param TC points to the TeleCommand packet that is being processed
47 * @param queue_id is the id of the queue which handles TM
47 * @param queue_id is the id of the queue which handles TM
48 *
48 *
49 * @return RTEMS directive status code:
49 * @return RTEMS directive status code:
50 * - RTEMS_SUCCESSFUL - message sent successfully
50 * - RTEMS_SUCCESSFUL - message sent successfully
51 * - RTEMS_INVALID_ID - invalid queue id
51 * - RTEMS_INVALID_ID - invalid queue id
52 * - RTEMS_INVALID_SIZE - invalid message size
52 * - RTEMS_INVALID_SIZE - invalid message size
53 * - RTEMS_INVALID_ADDRESS - buffer is NULL
53 * - RTEMS_INVALID_ADDRESS - buffer is NULL
54 * - RTEMS_UNSATISFIED - out of message buffers
54 * - RTEMS_UNSATISFIED - out of message buffers
55 * - RTEMS_TOO_MANY - queue s limit has been reached
55 * - RTEMS_TOO_MANY - queue s limit has been reached
56 *
56 *
57 */
57 */
58
58
59 rtems_status_code status;
59 rtems_status_code status;
60 Packet_TM_LFR_TC_EXE_SUCCESS_t TM;
60 Packet_TM_LFR_TC_EXE_SUCCESS_t TM;
61 unsigned char messageSize;
61 unsigned char messageSize;
62
62
63 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
63 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
64 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
64 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
65 TM.reserved = DEFAULT_RESERVED;
65 TM.reserved = DEFAULT_RESERVED;
66 TM.userApplication = CCSDS_USER_APP;
66 TM.userApplication = CCSDS_USER_APP;
67 // PACKET HEADER
67 // PACKET HEADER
68 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
68 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
69 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
69 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
70 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
70 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
71 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_SUCCESS >> SHIFT_1_BYTE);
71 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_SUCCESS >> SHIFT_1_BYTE);
72 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_SUCCESS );
72 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_SUCCESS );
73 // DATA FIELD HEADER
73 // DATA FIELD HEADER
74 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
74 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
75 TM.serviceType = TM_TYPE_TC_EXE;
75 TM.serviceType = TM_TYPE_TC_EXE;
76 TM.serviceSubType = TM_SUBTYPE_EXE_OK;
76 TM.serviceSubType = TM_SUBTYPE_EXE_OK;
77 TM.destinationID = TC->sourceID;
77 TM.destinationID = TC->sourceID;
78 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
78 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
79 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
79 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
80 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
80 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
81 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
81 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
82 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
82 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
83 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
83 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
84 //
84 //
85 TM.telecommand_pkt_id[0] = TC->packetID[0];
85 TM.telecommand_pkt_id[0] = TC->packetID[0];
86 TM.telecommand_pkt_id[1] = TC->packetID[1];
86 TM.telecommand_pkt_id[1] = TC->packetID[1];
87 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
87 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
88 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
88 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
89
89
90 messageSize = PACKET_LENGTH_TC_EXE_SUCCESS + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
90 messageSize = PACKET_LENGTH_TC_EXE_SUCCESS + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
91
91
92 // SEND DATA
92 // SEND DATA
93 status = rtems_message_queue_send( queue_id, &TM, messageSize);
93 status = rtems_message_queue_send( queue_id, &TM, messageSize);
94 if (status != RTEMS_SUCCESSFUL) {
94 if (status != RTEMS_SUCCESSFUL) {
95 PRINTF("in send_tm_lfr_tc_exe_success *** ERR\n")
95 PRINTF("in send_tm_lfr_tc_exe_success *** ERR\n")
96 }
96 }
97
97
98 // UPDATE HK FIELDS
98 // UPDATE HK FIELDS
99 update_last_TC_exe( TC, TM.time );
99 update_last_TC_exe( TC, TM.time );
100
100
101 return status;
101 return status;
102 }
102 }
103
103
104 int send_tm_lfr_tc_exe_inconsistent( ccsdsTelecommandPacket_t *TC, rtems_id queue_id,
104 int send_tm_lfr_tc_exe_inconsistent( ccsdsTelecommandPacket_t *TC, rtems_id queue_id,
105 unsigned char byte_position, unsigned char rcv_value )
105 unsigned char byte_position, unsigned char rcv_value )
106 {
106 {
107 /** This function sends a TM_LFR_TC_EXE_INCONSISTENT packet in the dedicated RTEMS message queue.
107 /** This function sends a TM_LFR_TC_EXE_INCONSISTENT packet in the dedicated RTEMS message queue.
108 *
108 *
109 * @param TC points to the TeleCommand packet that is being processed
109 * @param TC points to the TeleCommand packet that is being processed
110 * @param queue_id is the id of the queue which handles TM
110 * @param queue_id is the id of the queue which handles TM
111 * @param byte_position is the byte position of the MSB of the parameter that has been seen as inconsistent
111 * @param byte_position is the byte position of the MSB of the parameter that has been seen as inconsistent
112 * @param rcv_value is the value of the LSB of the parameter that has been detected as inconsistent
112 * @param rcv_value is the value of the LSB of the parameter that has been detected as inconsistent
113 *
113 *
114 * @return RTEMS directive status code:
114 * @return RTEMS directive status code:
115 * - RTEMS_SUCCESSFUL - message sent successfully
115 * - RTEMS_SUCCESSFUL - message sent successfully
116 * - RTEMS_INVALID_ID - invalid queue id
116 * - RTEMS_INVALID_ID - invalid queue id
117 * - RTEMS_INVALID_SIZE - invalid message size
117 * - RTEMS_INVALID_SIZE - invalid message size
118 * - RTEMS_INVALID_ADDRESS - buffer is NULL
118 * - RTEMS_INVALID_ADDRESS - buffer is NULL
119 * - RTEMS_UNSATISFIED - out of message buffers
119 * - RTEMS_UNSATISFIED - out of message buffers
120 * - RTEMS_TOO_MANY - queue s limit has been reached
120 * - RTEMS_TOO_MANY - queue s limit has been reached
121 *
121 *
122 */
122 */
123
123
124 rtems_status_code status;
124 rtems_status_code status;
125 Packet_TM_LFR_TC_EXE_INCONSISTENT_t TM;
125 Packet_TM_LFR_TC_EXE_INCONSISTENT_t TM;
126 unsigned char messageSize;
126 unsigned char messageSize;
127
127
128 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
128 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
129 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
129 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
130 TM.reserved = DEFAULT_RESERVED;
130 TM.reserved = DEFAULT_RESERVED;
131 TM.userApplication = CCSDS_USER_APP;
131 TM.userApplication = CCSDS_USER_APP;
132 // PACKET HEADER
132 // PACKET HEADER
133 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
133 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
134 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
134 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
135 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
135 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
136 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_INCONSISTENT >> SHIFT_1_BYTE);
136 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_INCONSISTENT >> SHIFT_1_BYTE);
137 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_INCONSISTENT );
137 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_INCONSISTENT );
138 // DATA FIELD HEADER
138 // DATA FIELD HEADER
139 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
139 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
140 TM.serviceType = TM_TYPE_TC_EXE;
140 TM.serviceType = TM_TYPE_TC_EXE;
141 TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
141 TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
142 TM.destinationID = TC->sourceID;
142 TM.destinationID = TC->sourceID;
143 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
143 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
144 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
144 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
145 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
145 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
146 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
146 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
147 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
147 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
148 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
148 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
149 //
149 //
150 TM.tc_failure_code[0] = (char) (WRONG_APP_DATA >> SHIFT_1_BYTE);
150 TM.tc_failure_code[0] = (char) (WRONG_APP_DATA >> SHIFT_1_BYTE);
151 TM.tc_failure_code[1] = (char) (WRONG_APP_DATA );
151 TM.tc_failure_code[1] = (char) (WRONG_APP_DATA );
152 TM.telecommand_pkt_id[0] = TC->packetID[0];
152 TM.telecommand_pkt_id[0] = TC->packetID[0];
153 TM.telecommand_pkt_id[1] = TC->packetID[1];
153 TM.telecommand_pkt_id[1] = TC->packetID[1];
154 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
154 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
155 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
155 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
156 TM.tc_service = TC->serviceType; // type of the rejected TC
156 TM.tc_service = TC->serviceType; // type of the rejected TC
157 TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC
157 TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC
158 TM.byte_position = byte_position;
158 TM.byte_position = byte_position;
159 TM.rcv_value = (unsigned char) rcv_value;
159 TM.rcv_value = (unsigned char) rcv_value;
160
160
161 messageSize = PACKET_LENGTH_TC_EXE_INCONSISTENT + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
161 messageSize = PACKET_LENGTH_TC_EXE_INCONSISTENT + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
162
162
163 // SEND DATA
163 // SEND DATA
164 status = rtems_message_queue_send( queue_id, &TM, messageSize);
164 status = rtems_message_queue_send( queue_id, &TM, messageSize);
165 if (status != RTEMS_SUCCESSFUL) {
165 if (status != RTEMS_SUCCESSFUL) {
166 PRINTF("in send_tm_lfr_tc_exe_inconsistent *** ERR\n")
166 PRINTF("in send_tm_lfr_tc_exe_inconsistent *** ERR\n")
167 }
167 }
168
168
169 // UPDATE HK FIELDS
169 // UPDATE HK FIELDS
170 update_last_TC_rej( TC, TM.time );
170 update_last_TC_rej( TC, TM.time );
171
171
172 return status;
172 return status;
173 }
173 }
174
174
175 int send_tm_lfr_tc_exe_not_executable( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
175 int send_tm_lfr_tc_exe_not_executable( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
176 {
176 {
177 /** This function sends a TM_LFR_TC_EXE_NOT_EXECUTABLE packet in the dedicated RTEMS message queue.
177 /** This function sends a TM_LFR_TC_EXE_NOT_EXECUTABLE packet in the dedicated RTEMS message queue.
178 *
178 *
179 * @param TC points to the TeleCommand packet that is being processed
179 * @param TC points to the TeleCommand packet that is being processed
180 * @param queue_id is the id of the queue which handles TM
180 * @param queue_id is the id of the queue which handles TM
181 *
181 *
182 * @return RTEMS directive status code:
182 * @return RTEMS directive status code:
183 * - RTEMS_SUCCESSFUL - message sent successfully
183 * - RTEMS_SUCCESSFUL - message sent successfully
184 * - RTEMS_INVALID_ID - invalid queue id
184 * - RTEMS_INVALID_ID - invalid queue id
185 * - RTEMS_INVALID_SIZE - invalid message size
185 * - RTEMS_INVALID_SIZE - invalid message size
186 * - RTEMS_INVALID_ADDRESS - buffer is NULL
186 * - RTEMS_INVALID_ADDRESS - buffer is NULL
187 * - RTEMS_UNSATISFIED - out of message buffers
187 * - RTEMS_UNSATISFIED - out of message buffers
188 * - RTEMS_TOO_MANY - queue s limit has been reached
188 * - RTEMS_TOO_MANY - queue s limit has been reached
189 *
189 *
190 */
190 */
191
191
192 rtems_status_code status;
192 rtems_status_code status;
193 Packet_TM_LFR_TC_EXE_NOT_EXECUTABLE_t TM;
193 Packet_TM_LFR_TC_EXE_NOT_EXECUTABLE_t TM;
194 unsigned char messageSize;
194 unsigned char messageSize;
195
195
196 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
196 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
197 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
197 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
198 TM.reserved = DEFAULT_RESERVED;
198 TM.reserved = DEFAULT_RESERVED;
199 TM.userApplication = CCSDS_USER_APP;
199 TM.userApplication = CCSDS_USER_APP;
200 // PACKET HEADER
200 // PACKET HEADER
201 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
201 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
202 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
202 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
203 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
203 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
204 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_EXECUTABLE >> SHIFT_1_BYTE);
204 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_EXECUTABLE >> SHIFT_1_BYTE);
205 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_EXECUTABLE );
205 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_EXECUTABLE );
206 // DATA FIELD HEADER
206 // DATA FIELD HEADER
207 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
207 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
208 TM.serviceType = TM_TYPE_TC_EXE;
208 TM.serviceType = TM_TYPE_TC_EXE;
209 TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
209 TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
210 TM.destinationID = TC->sourceID; // default destination id
210 TM.destinationID = TC->sourceID; // default destination id
211 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
211 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
212 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
212 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
213 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
213 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
214 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
214 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
215 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
215 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
216 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
216 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
217 //
217 //
218 TM.tc_failure_code[0] = (char) (TC_NOT_EXE >> SHIFT_1_BYTE);
218 TM.tc_failure_code[0] = (char) (TC_NOT_EXE >> SHIFT_1_BYTE);
219 TM.tc_failure_code[1] = (char) (TC_NOT_EXE );
219 TM.tc_failure_code[1] = (char) (TC_NOT_EXE );
220 TM.telecommand_pkt_id[0] = TC->packetID[0];
220 TM.telecommand_pkt_id[0] = TC->packetID[0];
221 TM.telecommand_pkt_id[1] = TC->packetID[1];
221 TM.telecommand_pkt_id[1] = TC->packetID[1];
222 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
222 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
223 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
223 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
224 TM.tc_service = TC->serviceType; // type of the rejected TC
224 TM.tc_service = TC->serviceType; // type of the rejected TC
225 TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC
225 TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC
226 TM.lfr_status_word[0] = housekeeping_packet.lfr_status_word[0];
226 TM.lfr_status_word[0] = housekeeping_packet.lfr_status_word[0];
227 TM.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1];
227 TM.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1];
228
228
229 messageSize = PACKET_LENGTH_TC_EXE_NOT_EXECUTABLE + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
229 messageSize = PACKET_LENGTH_TC_EXE_NOT_EXECUTABLE + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
230
230
231 // SEND DATA
231 // SEND DATA
232 status = rtems_message_queue_send( queue_id, &TM, messageSize);
232 status = rtems_message_queue_send( queue_id, &TM, messageSize);
233 if (status != RTEMS_SUCCESSFUL) {
233 if (status != RTEMS_SUCCESSFUL) {
234 PRINTF("in send_tm_lfr_tc_exe_not_executable *** ERR\n")
234 PRINTF("in send_tm_lfr_tc_exe_not_executable *** ERR\n")
235 }
235 }
236
236
237 // UPDATE HK FIELDS
237 // UPDATE HK FIELDS
238 update_last_TC_rej( TC, TM.time );
238 update_last_TC_rej( TC, TM.time );
239
239
240 return status;
240 return status;
241 }
241 }
242
242
243 #ifdef DENABLE_DEAD_CODE
243 int send_tm_lfr_tc_exe_not_implemented( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time )
244 int send_tm_lfr_tc_exe_not_implemented( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time )
244 {
245 {
245 /** This function sends a TM_LFR_TC_EXE_NOT_IMPLEMENTED packet in the dedicated RTEMS message queue.
246 /** This function sends a TM_LFR_TC_EXE_NOT_IMPLEMENTED packet in the dedicated RTEMS message queue.
246 *
247 *
247 * @param TC points to the TeleCommand packet that is being processed
248 * @param TC points to the TeleCommand packet that is being processed
248 * @param queue_id is the id of the queue which handles TM
249 * @param queue_id is the id of the queue which handles TM
249 *
250 *
250 * @return RTEMS directive status code:
251 * @return RTEMS directive status code:
251 * - RTEMS_SUCCESSFUL - message sent successfully
252 * - RTEMS_SUCCESSFUL - message sent successfully
252 * - RTEMS_INVALID_ID - invalid queue id
253 * - RTEMS_INVALID_ID - invalid queue id
253 * - RTEMS_INVALID_SIZE - invalid message size
254 * - RTEMS_INVALID_SIZE - invalid message size
254 * - RTEMS_INVALID_ADDRESS - buffer is NULL
255 * - RTEMS_INVALID_ADDRESS - buffer is NULL
255 * - RTEMS_UNSATISFIED - out of message buffers
256 * - RTEMS_UNSATISFIED - out of message buffers
256 * - RTEMS_TOO_MANY - queue s limit has been reached
257 * - RTEMS_TOO_MANY - queue s limit has been reached
257 *
258 *
258 */
259 */
259
260
260 rtems_status_code status;
261 rtems_status_code status;
261 Packet_TM_LFR_TC_EXE_NOT_IMPLEMENTED_t TM;
262 Packet_TM_LFR_TC_EXE_NOT_IMPLEMENTED_t TM;
262 unsigned char messageSize;
263 unsigned char messageSize;
263
264
264 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
265 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
265 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
266 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
266 TM.reserved = DEFAULT_RESERVED;
267 TM.reserved = DEFAULT_RESERVED;
267 TM.userApplication = CCSDS_USER_APP;
268 TM.userApplication = CCSDS_USER_APP;
268 // PACKET HEADER
269 // PACKET HEADER
269 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
270 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
270 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
271 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
271 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
272 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
272 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_IMPLEMENTED >> SHIFT_1_BYTE);
273 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_IMPLEMENTED >> SHIFT_1_BYTE);
273 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_IMPLEMENTED );
274 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_IMPLEMENTED );
274 // DATA FIELD HEADER
275 // DATA FIELD HEADER
275 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
276 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
276 TM.serviceType = TM_TYPE_TC_EXE;
277 TM.serviceType = TM_TYPE_TC_EXE;
277 TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
278 TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
278 TM.destinationID = TC->sourceID; // default destination id
279 TM.destinationID = TC->sourceID; // default destination id
279 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
280 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
280 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
281 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
281 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
282 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
282 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
283 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
283 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
284 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
284 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
285 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
285 //
286 //
286 TM.tc_failure_code[0] = (char) (FUNCT_NOT_IMPL >> SHIFT_1_BYTE);
287 TM.tc_failure_code[0] = (char) (FUNCT_NOT_IMPL >> SHIFT_1_BYTE);
287 TM.tc_failure_code[1] = (char) (FUNCT_NOT_IMPL );
288 TM.tc_failure_code[1] = (char) (FUNCT_NOT_IMPL );
288 TM.telecommand_pkt_id[0] = TC->packetID[0];
289 TM.telecommand_pkt_id[0] = TC->packetID[0];
289 TM.telecommand_pkt_id[1] = TC->packetID[1];
290 TM.telecommand_pkt_id[1] = TC->packetID[1];
290 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
291 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
291 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
292 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
292 TM.tc_service = TC->serviceType; // type of the rejected TC
293 TM.tc_service = TC->serviceType; // type of the rejected TC
293 TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC
294 TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC
294
295
295 messageSize = PACKET_LENGTH_TC_EXE_NOT_IMPLEMENTED + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
296 messageSize = PACKET_LENGTH_TC_EXE_NOT_IMPLEMENTED + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
296
297
297 // SEND DATA
298 // SEND DATA
298 status = rtems_message_queue_send( queue_id, &TM, messageSize);
299 status = rtems_message_queue_send( queue_id, &TM, messageSize);
299 if (status != RTEMS_SUCCESSFUL) {
300 if (status != RTEMS_SUCCESSFUL) {
300 PRINTF("in send_tm_lfr_tc_exe_not_implemented *** ERR\n")
301 PRINTF("in send_tm_lfr_tc_exe_not_implemented *** ERR\n")
301 }
302 }
302
303
303 // UPDATE HK FIELDS
304 // UPDATE HK FIELDS
304 update_last_TC_rej( TC, TM.time );
305 update_last_TC_rej( TC, TM.time );
305
306
306 return status;
307 return status;
307 }
308 }
309 #endif
308
310
309 int send_tm_lfr_tc_exe_error( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
311 int send_tm_lfr_tc_exe_error( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
310 {
312 {
311 /** This function sends a TM_LFR_TC_EXE_ERROR packet in the dedicated RTEMS message queue.
313 /** This function sends a TM_LFR_TC_EXE_ERROR packet in the dedicated RTEMS message queue.
312 *
314 *
313 * @param TC points to the TeleCommand packet that is being processed
315 * @param TC points to the TeleCommand packet that is being processed
314 * @param queue_id is the id of the queue which handles TM
316 * @param queue_id is the id of the queue which handles TM
315 *
317 *
316 * @return RTEMS directive status code:
318 * @return RTEMS directive status code:
317 * - RTEMS_SUCCESSFUL - message sent successfully
319 * - RTEMS_SUCCESSFUL - message sent successfully
318 * - RTEMS_INVALID_ID - invalid queue id
320 * - RTEMS_INVALID_ID - invalid queue id
319 * - RTEMS_INVALID_SIZE - invalid message size
321 * - RTEMS_INVALID_SIZE - invalid message size
320 * - RTEMS_INVALID_ADDRESS - buffer is NULL
322 * - RTEMS_INVALID_ADDRESS - buffer is NULL
321 * - RTEMS_UNSATISFIED - out of message buffers
323 * - RTEMS_UNSATISFIED - out of message buffers
322 * - RTEMS_TOO_MANY - queue s limit has been reached
324 * - RTEMS_TOO_MANY - queue s limit has been reached
323 *
325 *
324 */
326 */
325
327
326 rtems_status_code status;
328 rtems_status_code status;
327 Packet_TM_LFR_TC_EXE_ERROR_t TM;
329 Packet_TM_LFR_TC_EXE_ERROR_t TM;
328 unsigned char messageSize;
330 unsigned char messageSize;
329
331
330 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
332 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
331 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
333 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
332 TM.reserved = DEFAULT_RESERVED;
334 TM.reserved = DEFAULT_RESERVED;
333 TM.userApplication = CCSDS_USER_APP;
335 TM.userApplication = CCSDS_USER_APP;
334 // PACKET HEADER
336 // PACKET HEADER
335 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
337 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
336 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
338 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
337 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
339 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
338 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_ERROR >> SHIFT_1_BYTE);
340 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_ERROR >> SHIFT_1_BYTE);
339 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_ERROR );
341 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_ERROR );
340 // DATA FIELD HEADER
342 // DATA FIELD HEADER
341 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
343 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
342 TM.serviceType = TM_TYPE_TC_EXE;
344 TM.serviceType = TM_TYPE_TC_EXE;
343 TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
345 TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
344 TM.destinationID = TC->sourceID; // default destination id
346 TM.destinationID = TC->sourceID; // default destination id
345 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
347 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
346 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
348 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
347 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
349 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
348 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
350 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
349 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
351 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
350 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
352 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
351 //
353 //
352 TM.tc_failure_code[0] = (char) (FAIL_DETECTED >> SHIFT_1_BYTE);
354 TM.tc_failure_code[0] = (char) (FAIL_DETECTED >> SHIFT_1_BYTE);
353 TM.tc_failure_code[1] = (char) (FAIL_DETECTED );
355 TM.tc_failure_code[1] = (char) (FAIL_DETECTED );
354 TM.telecommand_pkt_id[0] = TC->packetID[0];
356 TM.telecommand_pkt_id[0] = TC->packetID[0];
355 TM.telecommand_pkt_id[1] = TC->packetID[1];
357 TM.telecommand_pkt_id[1] = TC->packetID[1];
356 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
358 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
357 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
359 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
358 TM.tc_service = TC->serviceType; // type of the rejected TC
360 TM.tc_service = TC->serviceType; // type of the rejected TC
359 TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC
361 TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC
360
362
361 messageSize = PACKET_LENGTH_TC_EXE_ERROR + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
363 messageSize = PACKET_LENGTH_TC_EXE_ERROR + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
362
364
363 // SEND DATA
365 // SEND DATA
364 status = rtems_message_queue_send( queue_id, &TM, messageSize);
366 status = rtems_message_queue_send( queue_id, &TM, messageSize);
365 if (status != RTEMS_SUCCESSFUL) {
367 if (status != RTEMS_SUCCESSFUL) {
366 PRINTF("in send_tm_lfr_tc_exe_error *** ERR\n")
368 PRINTF("in send_tm_lfr_tc_exe_error *** ERR\n")
367 }
369 }
368
370
369 // UPDATE HK FIELDS
371 // UPDATE HK FIELDS
370 update_last_TC_rej( TC, TM.time );
372 update_last_TC_rej( TC, TM.time );
371
373
372 return status;
374 return status;
373 }
375 }
374
376
375 int send_tm_lfr_tc_exe_corrupted(ccsdsTelecommandPacket_t *TC, rtems_id queue_id,
377 int send_tm_lfr_tc_exe_corrupted(ccsdsTelecommandPacket_t *TC, rtems_id queue_id,
376 unsigned char *computed_CRC, unsigned char *currentTC_LEN_RCV,
378 unsigned char *computed_CRC, unsigned char *currentTC_LEN_RCV,
377 unsigned char destinationID )
379 unsigned char destinationID )
378 {
380 {
379 /** This function sends a TM_LFR_TC_EXE_CORRUPTED packet in the dedicated RTEMS message queue.
381 /** This function sends a TM_LFR_TC_EXE_CORRUPTED packet in the dedicated RTEMS message queue.
380 *
382 *
381 * @param TC points to the TeleCommand packet that is being processed
383 * @param TC points to the TeleCommand packet that is being processed
382 * @param queue_id is the id of the queue which handles TM
384 * @param queue_id is the id of the queue which handles TM
383 * @param computed_CRC points to a buffer of two bytes containing the CRC computed during the parsing of the TeleCommand
385 * @param computed_CRC points to a buffer of two bytes containing the CRC computed during the parsing of the TeleCommand
384 * @param currentTC_LEN_RCV points to a buffer of two bytes containing a packet size field computed on the received data
386 * @param currentTC_LEN_RCV points to a buffer of two bytes containing a packet size field computed on the received data
385 *
387 *
386 * @return RTEMS directive status code:
388 * @return RTEMS directive status code:
387 * - RTEMS_SUCCESSFUL - message sent successfully
389 * - RTEMS_SUCCESSFUL - message sent successfully
388 * - RTEMS_INVALID_ID - invalid queue id
390 * - RTEMS_INVALID_ID - invalid queue id
389 * - RTEMS_INVALID_SIZE - invalid message size
391 * - RTEMS_INVALID_SIZE - invalid message size
390 * - RTEMS_INVALID_ADDRESS - buffer is NULL
392 * - RTEMS_INVALID_ADDRESS - buffer is NULL
391 * - RTEMS_UNSATISFIED - out of message buffers
393 * - RTEMS_UNSATISFIED - out of message buffers
392 * - RTEMS_TOO_MANY - queue s limit has been reached
394 * - RTEMS_TOO_MANY - queue s limit has been reached
393 *
395 *
394 */
396 */
395
397
396 rtems_status_code status;
398 rtems_status_code status;
397 Packet_TM_LFR_TC_EXE_CORRUPTED_t TM;
399 Packet_TM_LFR_TC_EXE_CORRUPTED_t TM;
398 unsigned char messageSize;
400 unsigned char messageSize;
399 unsigned int packetLength;
401 unsigned int packetLength;
400 unsigned int estimatedPacketLength;
402 unsigned int estimatedPacketLength;
401 unsigned char *packetDataField;
403 unsigned char *packetDataField;
402
404
403 packetLength = (TC->packetLength[0] * CONST_256) + TC->packetLength[1]; // compute the packet length parameter written in the TC
405 packetLength = (TC->packetLength[0] * CONST_256) + TC->packetLength[1]; // compute the packet length parameter written in the TC
404 estimatedPacketLength = (unsigned int) ((currentTC_LEN_RCV[0] * CONST_256) + currentTC_LEN_RCV[1]);
406 estimatedPacketLength = (unsigned int) ((currentTC_LEN_RCV[0] * CONST_256) + currentTC_LEN_RCV[1]);
405 packetDataField = (unsigned char *) &TC->headerFlag_pusVersion_Ack; // get the beginning of the data field
407 packetDataField = (unsigned char *) &TC->headerFlag_pusVersion_Ack; // get the beginning of the data field
406
408
407 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
409 TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
408 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
410 TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
409 TM.reserved = DEFAULT_RESERVED;
411 TM.reserved = DEFAULT_RESERVED;
410 TM.userApplication = CCSDS_USER_APP;
412 TM.userApplication = CCSDS_USER_APP;
411 // PACKET HEADER
413 // PACKET HEADER
412 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
414 TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
413 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
415 TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE );
414 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
416 increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
415 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_CORRUPTED >> SHIFT_1_BYTE);
417 TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_CORRUPTED >> SHIFT_1_BYTE);
416 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_CORRUPTED );
418 TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_CORRUPTED );
417 // DATA FIELD HEADER
419 // DATA FIELD HEADER
418 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
420 TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
419 TM.serviceType = TM_TYPE_TC_EXE;
421 TM.serviceType = TM_TYPE_TC_EXE;
420 TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
422 TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
421 TM.destinationID = destinationID;
423 TM.destinationID = destinationID;
422 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
424 TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
423 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
425 TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
424 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
426 TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
425 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
427 TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
426 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
428 TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
427 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
429 TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
428 //
430 //
429 TM.tc_failure_code[0] = (unsigned char) (CORRUPTED >> SHIFT_1_BYTE);
431 TM.tc_failure_code[0] = (unsigned char) (CORRUPTED >> SHIFT_1_BYTE);
430 TM.tc_failure_code[1] = (unsigned char) (CORRUPTED );
432 TM.tc_failure_code[1] = (unsigned char) (CORRUPTED );
431 TM.telecommand_pkt_id[0] = TC->packetID[0];
433 TM.telecommand_pkt_id[0] = TC->packetID[0];
432 TM.telecommand_pkt_id[1] = TC->packetID[1];
434 TM.telecommand_pkt_id[1] = TC->packetID[1];
433 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
435 TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
434 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
436 TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
435 TM.tc_service = TC->serviceType; // type of the rejected TC
437 TM.tc_service = TC->serviceType; // type of the rejected TC
436 TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC
438 TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC
437 TM.pkt_len_rcv_value[0] = TC->packetLength[0];
439 TM.pkt_len_rcv_value[0] = TC->packetLength[0];
438 TM.pkt_len_rcv_value[1] = TC->packetLength[1];
440 TM.pkt_len_rcv_value[1] = TC->packetLength[1];
439 TM.pkt_datafieldsize_cnt[0] = currentTC_LEN_RCV[0];
441 TM.pkt_datafieldsize_cnt[0] = currentTC_LEN_RCV[0];
440 TM.pkt_datafieldsize_cnt[1] = currentTC_LEN_RCV[1];
442 TM.pkt_datafieldsize_cnt[1] = currentTC_LEN_RCV[1];
441 TM.rcv_crc[0] = packetDataField[ estimatedPacketLength - 1 ];
443 TM.rcv_crc[0] = packetDataField[ estimatedPacketLength - 1 ];
442 TM.rcv_crc[1] = packetDataField[ estimatedPacketLength ];
444 TM.rcv_crc[1] = packetDataField[ estimatedPacketLength ];
443 TM.computed_crc[0] = computed_CRC[0];
445 TM.computed_crc[0] = computed_CRC[0];
444 TM.computed_crc[1] = computed_CRC[1];
446 TM.computed_crc[1] = computed_CRC[1];
445
447
446 messageSize = PACKET_LENGTH_TC_EXE_CORRUPTED + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
448 messageSize = PACKET_LENGTH_TC_EXE_CORRUPTED + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
447
449
448 // SEND DATA
450 // SEND DATA
449 status = rtems_message_queue_send( queue_id, &TM, messageSize);
451 status = rtems_message_queue_send( queue_id, &TM, messageSize);
450 if (status != RTEMS_SUCCESSFUL) {
452 if (status != RTEMS_SUCCESSFUL) {
451 PRINTF("in send_tm_lfr_tc_exe_error *** ERR\n")
453 PRINTF("in send_tm_lfr_tc_exe_error *** ERR\n")
452 }
454 }
453
455
454 // UPDATE HK FIELDS
456 // UPDATE HK FIELDS
455 update_last_TC_rej( TC, TM.time );
457 update_last_TC_rej( TC, TM.time );
456
458
457 return status;
459 return status;
458 }
460 }
459
461
460 void increment_seq_counter_destination_id( unsigned char *packet_sequence_control, unsigned char destination_id )
462 void increment_seq_counter_destination_id( unsigned char *packet_sequence_control, unsigned char destination_id )
461 {
463 {
462 /** This function increment the packet sequence control parameter of a TC, depending on its destination ID.
464 /** This function increment the packet sequence control parameter of a TC, depending on its destination ID.
463 *
465 *
464 * @param packet_sequence_control points to the packet sequence control which will be incremented
466 * @param packet_sequence_control points to the packet sequence control which will be incremented
465 * @param destination_id is the destination ID of the TM, there is one counter by destination ID
467 * @param destination_id is the destination ID of the TM, there is one counter by destination ID
466 *
468 *
467 * If the destination ID is not known, a dedicated counter is incremented.
469 * If the destination ID is not known, a dedicated counter is incremented.
468 *
470 *
469 */
471 */
470
472
471 unsigned short sequence_cnt;
473 unsigned short sequence_cnt;
472 unsigned short segmentation_grouping_flag;
474 unsigned short segmentation_grouping_flag;
473 unsigned short new_packet_sequence_control;
475 unsigned short new_packet_sequence_control;
474 unsigned char i;
476 unsigned char i;
475
477
476 switch (destination_id)
478 switch (destination_id)
477 {
479 {
478 case SID_TC_GROUND:
480 case SID_TC_GROUND:
479 i = GROUND;
481 i = GROUND;
480 break;
482 break;
481 case SID_TC_MISSION_TIMELINE:
483 case SID_TC_MISSION_TIMELINE:
482 i = MISSION_TIMELINE;
484 i = MISSION_TIMELINE;
483 break;
485 break;
484 case SID_TC_TC_SEQUENCES:
486 case SID_TC_TC_SEQUENCES:
485 i = TC_SEQUENCES;
487 i = TC_SEQUENCES;
486 break;
488 break;
487 case SID_TC_RECOVERY_ACTION_CMD:
489 case SID_TC_RECOVERY_ACTION_CMD:
488 i = RECOVERY_ACTION_CMD;
490 i = RECOVERY_ACTION_CMD;
489 break;
491 break;
490 case SID_TC_BACKUP_MISSION_TIMELINE:
492 case SID_TC_BACKUP_MISSION_TIMELINE:
491 i = BACKUP_MISSION_TIMELINE;
493 i = BACKUP_MISSION_TIMELINE;
492 break;
494 break;
493 case SID_TC_DIRECT_CMD:
495 case SID_TC_DIRECT_CMD:
494 i = DIRECT_CMD;
496 i = DIRECT_CMD;
495 break;
497 break;
496 case SID_TC_SPARE_GRD_SRC1:
498 case SID_TC_SPARE_GRD_SRC1:
497 i = SPARE_GRD_SRC1;
499 i = SPARE_GRD_SRC1;
498 break;
500 break;
499 case SID_TC_SPARE_GRD_SRC2:
501 case SID_TC_SPARE_GRD_SRC2:
500 i = SPARE_GRD_SRC2;
502 i = SPARE_GRD_SRC2;
501 break;
503 break;
502 case SID_TC_OBCP:
504 case SID_TC_OBCP:
503 i = OBCP;
505 i = OBCP;
504 break;
506 break;
505 case SID_TC_SYSTEM_CONTROL:
507 case SID_TC_SYSTEM_CONTROL:
506 i = SYSTEM_CONTROL;
508 i = SYSTEM_CONTROL;
507 break;
509 break;
508 case SID_TC_AOCS:
510 case SID_TC_AOCS:
509 i = AOCS;
511 i = AOCS;
510 break;
512 break;
511 case SID_TC_RPW_INTERNAL:
513 case SID_TC_RPW_INTERNAL:
512 i = RPW_INTERNAL;
514 i = RPW_INTERNAL;
513 break;
515 break;
514 default:
516 default:
515 i = GROUND;
517 i = GROUND;
516 break;
518 break;
517 }
519 }
518
520
519 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << SHIFT_1_BYTE;
521 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << SHIFT_1_BYTE;
520 sequence_cnt = sequenceCounters_TC_EXE[ i ] & SEQ_CNT_MASK;
522 sequence_cnt = sequenceCounters_TC_EXE[ i ] & SEQ_CNT_MASK;
521
523
522 new_packet_sequence_control = segmentation_grouping_flag | sequence_cnt ;
524 new_packet_sequence_control = segmentation_grouping_flag | sequence_cnt ;
523
525
524 packet_sequence_control[0] = (unsigned char) (new_packet_sequence_control >> SHIFT_1_BYTE);
526 packet_sequence_control[0] = (unsigned char) (new_packet_sequence_control >> SHIFT_1_BYTE);
525 packet_sequence_control[1] = (unsigned char) (new_packet_sequence_control );
527 packet_sequence_control[1] = (unsigned char) (new_packet_sequence_control );
526
528
527 // increment the sequence counter
529 // increment the sequence counter
528 if ( sequenceCounters_TC_EXE[ i ] < SEQ_CNT_MAX )
530 if ( sequenceCounters_TC_EXE[ i ] < SEQ_CNT_MAX )
529 {
531 {
530 sequenceCounters_TC_EXE[ i ] = sequenceCounters_TC_EXE[ i ] + 1;
532 sequenceCounters_TC_EXE[ i ] = sequenceCounters_TC_EXE[ i ] + 1;
531 }
533 }
532 else
534 else
533 {
535 {
534 sequenceCounters_TC_EXE[ i ] = 0;
536 sequenceCounters_TC_EXE[ i ] = 0;
535 }
537 }
536 }
538 }
General Comments 0
You need to be logged in to leave comments. Login now