@@ -1,14 +1,14 | |||
|
1 |
cmake_minimum_required (VERSION 3. |
|
|
1 | cmake_minimum_required (VERSION 3.5) | |
|
2 | 2 | project (LFR_FSW) |
|
3 | 3 | |
|
4 | 4 | if(NOT CMAKE_BUILD_TYPE) |
|
5 | 5 | set(CMAKE_BUILD_TYPE "Release" CACHE STRING |
|
6 | 6 | "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) |
|
7 | 7 | endif(NOT CMAKE_BUILD_TYPE) |
|
8 | 8 | |
|
9 | 9 | set(LFR_BP_SRC ${CMAKE_CURRENT_SOURCE_DIR}/LFR_basic-parameters/basic_parameters.c) |
|
10 | 10 | |
|
11 | 11 | SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/sparc") |
|
12 | 12 | |
|
13 | 13 | add_subdirectory(libgcov) |
|
14 | 14 | add_subdirectory(src) |
@@ -1,117 +1,112 | |||
|
1 | 1 | #ifndef TC_HANDLER_H_INCLUDED |
|
2 | 2 | #define TC_HANDLER_H_INCLUDED |
|
3 | 3 | |
|
4 | 4 | #include <rtems.h> |
|
5 | 5 | #include <leon.h> |
|
6 | 6 | |
|
7 | 7 | #include "tc_load_dump_parameters.h" |
|
8 | 8 | #include "tc_acceptance.h" |
|
9 | 9 | #include "tm_lfr_tc_exe.h" |
|
10 | 10 | #include "wf_handler.h" |
|
11 | 11 | #include "fsw_processing.h" |
|
12 | 12 | |
|
13 | 13 | #include "lfr_cpu_usage_report.h" |
|
14 | 14 | |
|
15 | 15 | #define MAX_DELTA_COARSE_TIME 3 |
|
16 | 16 | #define NB_SCIENCE_TASKS 10 |
|
17 | 17 | #define NB_ASM_TASKS 6 |
|
18 | 18 | #define STATUS_0 0 |
|
19 | 19 | #define STATUS_1 1 |
|
20 | 20 | #define STATUS_2 2 |
|
21 | 21 | #define STATUS_3 3 |
|
22 | 22 | #define STATUS_4 4 |
|
23 | 23 | #define STATUS_5 5 |
|
24 | 24 | #define STATUS_6 6 |
|
25 | 25 | #define STATUS_7 7 |
|
26 | 26 | #define STATUS_8 8 |
|
27 | 27 | #define STATUS_9 9 |
|
28 | 28 | |
|
29 | 29 | #define CAL_F0 625. |
|
30 | 30 | #define CAL_F1 10000. |
|
31 | 31 | #define CAL_W0 (2. * pi * CAL_F0) |
|
32 | 32 | #define CAL_W1 (2. * pi * CAL_F1) |
|
33 | 33 | #define CAL_A0 1. |
|
34 | 34 | #define CAL_A1 2. |
|
35 | 35 | #define CAL_FS 160256.410 |
|
36 | 36 | #define CAL_SCALE_FACTOR (0.250 / 0.000654) // 191, 500 mVpp, 2 sinus waves => 500 mVpp each, amplitude = 250 mV |
|
37 | 37 | #define CAL_NB_PTS 256 |
|
38 | 38 | #define CAL_DATA_MASK 0xfff |
|
39 | 39 | #define CAL_F_DIVISOR 38 // 25 MHz => 160 256 (39 - 1) |
|
40 | 40 | #define CAL_F_DIVISOR_MIN 38 |
|
41 | 41 | #define CAL_F_DIVISOR_MAX (38*2*2*2*2) |
|
42 | 42 | // INTERLEAVED MODE |
|
43 | 43 | #define CAL_FS_INTER 240384.615 |
|
44 | 44 | #define CAL_NB_PTS_INTER 384 |
|
45 | 45 | #define CAL_DATA_MASK_INTER 0x3f |
|
46 | 46 | #define CAL_DATA_SHIFT_INTER 12 |
|
47 | 47 | #define BYTES_FOR_2_SAMPLES 3 // one need 3 bytes = 24 bits to store 3 samples of 12 bits in interleaved mode |
|
48 | 48 | #define STEPS_FOR_STORAGE_INTER 128 |
|
49 | 49 | #define CAL_F_DIVISOR_INTER 26 // 25 MHz => 240 384 |
|
50 | 50 | |
|
51 | 51 | extern unsigned int lastValidEnterModeTime; |
|
52 | 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 | 55 | // RTEMS TASK |
|
61 | 56 | rtems_task actn_task( rtems_task_argument unused ); |
|
62 | 57 | |
|
63 | 58 | //*********** |
|
64 | 59 | // TC ACTIONS |
|
65 | 60 | int action_reset( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time ); |
|
66 | 61 | int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id); |
|
67 | 62 | int action_update_info( ccsdsTelecommandPacket_t *TC, rtems_id queue_id ); |
|
68 | 63 | int action_enable_calibration( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time ); |
|
69 | 64 | int action_disable_calibration( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time ); |
|
70 | 65 | int action_update_time( ccsdsTelecommandPacket_t *TC); |
|
71 | 66 | |
|
72 | 67 | // mode transition |
|
73 | 68 | int check_mode_value( unsigned char requestedMode ); |
|
74 | 69 | int check_mode_transition( unsigned char requestedMode ); |
|
75 | 70 | void update_last_valid_transition_date( unsigned int transitionCoarseTime ); |
|
76 | 71 | int check_transition_date( unsigned int transitionCoarseTime ); |
|
77 | 72 | int stop_spectral_matrices( void ); |
|
78 | 73 | int stop_current_mode( void ); |
|
79 | 74 | int enter_mode_standby(void ); |
|
80 | 75 | int enter_mode_normal( unsigned int transitionCoarseTime ); |
|
81 | 76 | int enter_mode_burst( unsigned int transitionCoarseTime ); |
|
82 | 77 | int enter_mode_sbm1( unsigned int transitionCoarseTime ); |
|
83 | 78 | int enter_mode_sbm2( unsigned int transitionCoarseTime ); |
|
84 | 79 | int restart_science_tasks( unsigned char lfrRequestedMode ); |
|
85 | 80 | int restart_asm_tasks(unsigned char lfrRequestedMode ); |
|
86 | 81 | int suspend_science_tasks(void); |
|
87 | 82 | int suspend_asm_tasks( void ); |
|
88 | 83 | void launch_waveform_picker( unsigned char mode , unsigned int transitionCoarseTime ); |
|
89 | 84 | void launch_spectral_matrix( void ); |
|
90 | 85 | void set_sm_irq_onNewMatrix( unsigned char value ); |
|
91 | 86 | void set_sm_irq_onError( unsigned char value ); |
|
92 | 87 | |
|
93 | 88 | // other functions |
|
94 | 89 | void updateLFRCurrentMode(unsigned char requestedMode); |
|
95 | 90 | void set_lfr_soft_reset( unsigned char value ); |
|
96 | 91 | void reset_lfr( void ); |
|
97 | 92 | // CALIBRATION |
|
98 | 93 | void setCalibrationPrescaler( unsigned int prescaler ); |
|
99 | 94 | void setCalibrationDivisor( unsigned int divisionFactor ); |
|
100 | 95 | void setCalibrationData( void ); |
|
101 | 96 | void setCalibrationReload( bool state); |
|
102 | 97 | void setCalibrationEnable( bool state ); |
|
103 | 98 | void setCalibrationInterleaved( bool state ); |
|
104 | 99 | void setCalibration( bool state ); |
|
105 | 100 | void configureCalibration( bool interleaved ); |
|
106 | 101 | // |
|
107 | 102 | void update_last_TC_exe( ccsdsTelecommandPacket_t *TC , unsigned char *time ); |
|
108 | 103 | void update_last_TC_rej(ccsdsTelecommandPacket_t *TC , unsigned char *time ); |
|
109 | 104 | void close_action( ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id ); |
|
110 | 105 | |
|
111 | 106 | extern rtems_status_code get_message_queue_id_send( rtems_id *queue_id ); |
|
112 | 107 | extern rtems_status_code get_message_queue_id_recv( rtems_id *queue_id ); |
|
113 | 108 | |
|
114 | 109 | #endif // TC_HANDLER_H_INCLUDED |
|
115 | 110 | |
|
116 | 111 | |
|
117 | 112 |
@@ -1,20 +1,20 | |||
|
1 |
cmake_minimum_required(VERSION 3. |
|
|
1 | cmake_minimum_required(VERSION 3.5) | |
|
2 | 2 | project(libgcov C) |
|
3 | 3 | include(sparc-rtems) |
|
4 | 4 | include(cppcheck) |
|
5 | 5 | |
|
6 | 6 | set(LIB_GCOV_SOURCES |
|
7 | 7 | gcov-io.c |
|
8 | 8 | gcov-io.h |
|
9 | 9 | gcov-iov.h |
|
10 | 10 | libgcov.c |
|
11 | 11 | ) |
|
12 | 12 | if(Coverage) |
|
13 |
|
|
|
13 | add_definitions(-DGCOV_USE_EXIT) | |
|
14 | 14 | add_definitions(-DGCOV_ENABLED) |
|
15 | 15 | endif() |
|
16 | 16 | add_library(gcov STATIC ${LIB_GCOV_SOURCES}) |
|
17 | 17 | |
|
18 | 18 | add_custom_target(gcovr |
|
19 | 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 | 1 | set(rtems_dir /opt/rtems-4.10/) |
|
2 | 2 | |
|
3 | 3 | set(CMAKE_SYSTEM_NAME rtems) |
|
4 | 4 | set(CMAKE_C_COMPILER ${rtems_dir}/bin/sparc-rtems-gcc) |
|
5 | 5 | set(CMAKE_CXX_COMPILER ${rtems_dir}/bin/sparc-rtems-g++) |
|
6 | 6 | set(CMAKE_LINKER ${rtems_dir}/bin/sparc-rtems-g++) |
|
7 | 7 | SET(CMAKE_EXE_LINKER_FLAGS "-static") |
|
8 | 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 | 10 | option(Coverage "Enables code coverage" OFF) |
|
11 | 11 | |
|
12 | 12 | |
|
13 | 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 | 17 | if(fix-b2bst) |
|
18 | 18 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mfix-b2bst") |
|
19 | 19 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -mfix-b2bst") |
|
20 | 20 | endif() |
|
21 | 21 | |
|
22 | 22 | |
|
23 | 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 | 25 | include_directories("${rtems_dir}/sparc-rtems/leon3/lib/include") |
|
26 | 26 | |
|
27 | 27 | function (check_b2bst target bin) |
|
28 | 28 | add_custom_command(TARGET ${target} |
|
29 | 29 | POST_BUILD |
|
30 | 30 | COMMAND ${rtems_dir}/bin/sparc-rtems-objdump -d ${bin}/${target} | ${CMAKE_SOURCE_DIR}/sparc/leon3ft-b2bst-scan.tcl |
|
31 | 31 | ) |
|
32 | 32 | endfunction() |
|
33 | 33 | |
|
34 | 34 | function (build_srec target bin rev) |
|
35 | 35 | add_custom_command(TARGET ${target} |
|
36 | 36 | POST_BUILD |
|
37 | 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 | 39 | endfunction() |
@@ -1,130 +1,136 | |||
|
1 |
cmake_minimum_required (VERSION 3. |
|
|
1 | cmake_minimum_required (VERSION 3.5) | |
|
2 | 2 | project (fsw) |
|
3 | 3 | |
|
4 | 4 | include(sparc-rtems) |
|
5 | 5 | include(cppcheck) |
|
6 | 6 | |
|
7 | 7 | include_directories("../header" |
|
8 |
|
|
|
9 |
|
|
|
10 |
|
|
|
11 |
|
|
|
8 | "../header/lfr_common_headers" | |
|
9 | "../header/processing" | |
|
10 | "../LFR_basic-parameters" | |
|
11 | "../src") | |
|
12 | 12 | |
|
13 | 13 | set(SOURCES wf_handler.c |
|
14 |
|
|
|
15 |
|
|
|
16 |
|
|
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
|
20 |
|
|
|
21 |
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
|
|
|
25 |
|
|
|
26 |
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
|
31 |
|
|
|
32 |
|
|
|
33 |
|
|
|
34 |
|
|
|
35 |
|
|
|
36 |
|
|
|
37 |
|
|
|
38 |
|
|
|
39 |
|
|
|
40 |
|
|
|
41 |
|
|
|
42 |
|
|
|
43 |
|
|
|
44 |
|
|
|
45 |
|
|
|
46 |
|
|
|
47 |
|
|
|
48 |
|
|
|
49 |
|
|
|
50 |
|
|
|
51 | ) | |
|
14 | tc_handler.c | |
|
15 | fsw_misc.c | |
|
16 | fsw_init.c | |
|
17 | fsw_globals.c | |
|
18 | fsw_spacewire.c | |
|
19 | tc_load_dump_parameters.c | |
|
20 | tm_lfr_tc_exe.c | |
|
21 | tc_acceptance.c | |
|
22 | processing/fsw_processing.c | |
|
23 | processing/avf0_prc0.c | |
|
24 | processing/avf1_prc1.c | |
|
25 | processing/avf2_prc2.c | |
|
26 | lfr_cpu_usage_report.c | |
|
27 | ${LFR_BP_SRC} | |
|
28 | ../header/wf_handler.h | |
|
29 | ../header/tc_handler.h | |
|
30 | ../header/grlib_regs.h | |
|
31 | ../header/fsw_misc.h | |
|
32 | ../header/fsw_init.h | |
|
33 | ../header/fsw_spacewire.h | |
|
34 | ../header/tc_load_dump_parameters.h | |
|
35 | ../header/tm_lfr_tc_exe.h | |
|
36 | ../header/tc_acceptance.h | |
|
37 | ../header/processing/fsw_processing.h | |
|
38 | ../header/processing/avf0_prc0.h | |
|
39 | ../header/processing/avf1_prc1.h | |
|
40 | ../header/processing/avf2_prc2.h | |
|
41 | ../header/fsw_params_wf_handler.h | |
|
42 | ../header/lfr_cpu_usage_report.h | |
|
43 | ../header/lfr_common_headers/ccsds_types.h | |
|
44 | ../header/lfr_common_headers/fsw_params.h | |
|
45 | ../header/lfr_common_headers/fsw_params_nb_bytes.h | |
|
46 | ../header/lfr_common_headers/fsw_params_processing.h | |
|
47 | ../header/lfr_common_headers/tm_byte_positions.h | |
|
48 | ../LFR_basic-parameters/basic_parameters.h | |
|
49 | ../LFR_basic-parameters/basic_parameters_params.h | |
|
50 | ../header/GscMemoryLPP.hpp | |
|
51 | ) | |
|
52 | 52 | |
|
53 | 53 | |
|
54 | 54 | option(FSW_verbose "Enable verbose LFR" OFF) |
|
55 | 55 | option(FSW_boot_messages "Enable LFR boot messages" OFF) |
|
56 | 56 | option(FSW_debug_messages "Enable LFR debug messages" OFF) |
|
57 | 57 | option(FSW_cpu_usage_report "Enable LFR cpu usage report" OFF) |
|
58 | 58 | option(FSW_stack_report "Enable LFR stack report" OFF) |
|
59 | 59 | option(FSW_vhdl_dev "?" OFF) |
|
60 | 60 | option(FSW_lpp_dpu_destid "Set to debug at LPP" OFF) |
|
61 | 61 | option(FSW_debug_watchdog "Enable debug watchdog" OFF) |
|
62 | 62 | option(FSW_debug_tch "?" OFF) |
|
63 | 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 | 66 | set(SW_VERSION_N1 "3" CACHE STRING "Choose N1 FSW Version." FORCE) |
|
66 | 67 | set(SW_VERSION_N2 "2" CACHE STRING "Choose N2 FSW Version." FORCE) |
|
67 | 68 | set(SW_VERSION_N3 "0" CACHE STRING "Choose N3 FSW Version." FORCE) |
|
68 | 69 | set(SW_VERSION_N4 "22" CACHE STRING "Choose N4 FSW Version." FORCE) |
|
69 | 70 | |
|
70 | 71 | if(FSW_verbose) |
|
71 |
|
|
|
72 | add_definitions(-DPRINT_MESSAGES_ON_CONSOLE) | |
|
72 | 73 | endif() |
|
73 | 74 | if(FSW_boot_messages) |
|
74 |
|
|
|
75 | add_definitions(-DBOOT_MESSAGES) | |
|
75 | 76 | endif() |
|
76 | 77 | if(FSW_debug_messages) |
|
77 |
|
|
|
78 | add_definitions(-DDEBUG_MESSAGES) | |
|
78 | 79 | endif() |
|
79 | 80 | if(FSW_cpu_usage_report) |
|
80 |
|
|
|
81 | add_definitions(-DPRINT_TASK_STATISTICS) | |
|
81 | 82 | endif() |
|
82 | 83 | if(FSW_stack_report) |
|
83 |
|
|
|
84 | add_definitions(-DPRINT_STACK_REPORT) | |
|
84 | 85 | endif() |
|
85 | 86 | if(FSW_vhdl_dev) |
|
86 |
|
|
|
87 | add_definitions(-DVHDL_DEV) | |
|
87 | 88 | endif() |
|
88 | 89 | if(FSW_lpp_dpu_destid) |
|
89 |
|
|
|
90 | add_definitions(-DLPP_DPU_DESTID) | |
|
90 | 91 | endif() |
|
91 | 92 | if(FSW_debug_watchdog) |
|
92 |
|
|
|
93 | add_definitions(-DDEBUG_WATCHDOG) | |
|
93 | 94 | endif() |
|
94 | 95 | if(FSW_debug_tch) |
|
95 |
|
|
|
96 | add_definitions(-DDEBUG_TCH) | |
|
96 | 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 | 106 | add_definitions(-DMSB_FIRST_TCH) |
|
101 | 107 | |
|
102 | 108 | add_definitions(-DSWVERSION=-1-0) |
|
103 | 109 | add_definitions(-DSW_VERSION_N1=${SW_VERSION_N1}) |
|
104 | 110 | add_definitions(-DSW_VERSION_N2=${SW_VERSION_N2}) |
|
105 | 111 | add_definitions(-DSW_VERSION_N3=${SW_VERSION_N3}) |
|
106 | 112 | add_definitions(-DSW_VERSION_N4=${SW_VERSION_N4}) |
|
107 | 113 | |
|
108 | 114 | add_executable(fsw ${SOURCES}) |
|
109 | 115 | |
|
110 | 116 | if(FSW_Instrument_Scrubbing) |
|
111 | 117 | add_definitions(-DENABLE_SCRUBBING_COUNTER) |
|
112 | 118 | endif() |
|
113 | 119 | |
|
114 | 120 | if(Coverage) |
|
115 | 121 | target_link_libraries(fsw gcov) |
|
116 | 122 | SET_TARGET_PROPERTIES(fsw PROPERTIES COMPILE_FLAGS "-fprofile-arcs -ftest-coverage") |
|
117 | 123 | endif() |
|
118 | 124 | |
|
119 | 125 | |
|
120 | 126 | if(fix-b2bst) |
|
121 | 127 | check_b2bst(fsw ${CMAKE_CURRENT_BINARY_DIR}) |
|
122 | 128 | endif() |
|
123 | 129 | |
|
124 | 130 | if(NOT FSW_lpp_dpu_destid) |
|
125 | 131 | build_srec(fsw ${CMAKE_CURRENT_BINARY_DIR} "${SW_VERSION_N1}-${SW_VERSION_N2}-${SW_VERSION_N3}-${SW_VERSION_N4}") |
|
126 | 132 | endif() |
|
127 | 133 | |
|
128 | 134 | |
|
129 | 135 | #add_test_cppcheck(fsw STYLE UNUSED_FUNCTIONS POSSIBLE_ERROR MISSING_INCLUDE) |
|
130 | 136 |
@@ -1,1109 +1,1111 | |||
|
1 | 1 | /*------------------------------------------------------------------------------ |
|
2 | 2 | -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW), |
|
3 | 3 | -- This file is a part of the LFR FSW |
|
4 | 4 | -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS |
|
5 | 5 | -- |
|
6 | 6 | -- This program is free software; you can redistribute it and/or modify |
|
7 | 7 | -- it under the terms of the GNU General Public License as published by |
|
8 | 8 | -- the Free Software Foundation; either version 2 of the License, or |
|
9 | 9 | -- (at your option) any later version. |
|
10 | 10 | -- |
|
11 | 11 | -- This program is distributed in the hope that it will be useful, |
|
12 | 12 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 | 13 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 | 14 | -- GNU General Public License for more details. |
|
15 | 15 | -- |
|
16 | 16 | -- You should have received a copy of the GNU General Public License |
|
17 | 17 | -- along with this program; if not, write to the Free Software |
|
18 | 18 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
19 | 19 | -------------------------------------------------------------------------------*/ |
|
20 | 20 | /*-- Author : Paul Leroy |
|
21 | 21 | -- Contact : Alexis Jeandet |
|
22 | 22 | -- Mail : alexis.jeandet@lpp.polytechnique.fr |
|
23 | 23 | ----------------------------------------------------------------------------*/ |
|
24 | 24 | |
|
25 | 25 | /** General usage functions and RTEMS tasks. |
|
26 | 26 | * |
|
27 | 27 | * @file |
|
28 | 28 | * @author P. LEROY |
|
29 | 29 | * |
|
30 | 30 | */ |
|
31 | 31 | |
|
32 | 32 | #include "fsw_misc.h" |
|
33 | 33 | |
|
34 | 34 | int16_t hk_lfr_sc_v_f3_as_int16 = 0; |
|
35 | 35 | int16_t hk_lfr_sc_e1_f3_as_int16 = 0; |
|
36 | 36 | int16_t hk_lfr_sc_e2_f3_as_int16 = 0; |
|
37 | 37 | |
|
38 | 38 | void timer_configure(unsigned char timer, unsigned int clock_divider, |
|
39 | 39 | unsigned char interrupt_level, rtems_isr (*timer_isr)() ) |
|
40 | 40 | { |
|
41 | 41 | /** This function configures a GPTIMER timer instantiated in the VHDL design. |
|
42 | 42 | * |
|
43 | 43 | * @param gptimer_regs points to the APB registers of the GPTIMER IP core. |
|
44 | 44 | * @param timer is the number of the timer in the IP core (several timers can be instantiated). |
|
45 | 45 | * @param clock_divider is the divider of the 1 MHz clock that will be configured. |
|
46 | 46 | * @param interrupt_level is the interrupt level that the timer drives. |
|
47 | 47 | * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer. |
|
48 | 48 | * |
|
49 | 49 | * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76 |
|
50 | 50 | * |
|
51 | 51 | */ |
|
52 | 52 | |
|
53 | 53 | rtems_status_code status; |
|
54 | 54 | rtems_isr_entry old_isr_handler; |
|
55 | 55 | |
|
56 | 56 | old_isr_handler = NULL; |
|
57 | 57 | |
|
58 | 58 | gptimer_regs->timer[timer].ctrl = INIT_CHAR; // reset the control register |
|
59 | 59 | |
|
60 | 60 | status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels |
|
61 | 61 | if (status!=RTEMS_SUCCESSFUL) |
|
62 | 62 | { |
|
63 | 63 | PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n") |
|
64 | 64 | } |
|
65 | 65 | |
|
66 | 66 | timer_set_clock_divider( timer, clock_divider); |
|
67 | 67 | } |
|
68 | 68 | |
|
69 | #ifdef ENABLE_DEAD_CODE | |
|
69 | 70 | void timer_start(unsigned char timer) |
|
70 | 71 | { |
|
71 | 72 | /** This function starts a GPTIMER timer. |
|
72 | 73 | * |
|
73 | 74 | * @param gptimer_regs points to the APB registers of the GPTIMER IP core. |
|
74 | 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 | 79 | gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_CLEAR_IRQ; |
|
79 | 80 | gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_LD; |
|
80 | 81 | gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_EN; |
|
81 | 82 | gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_RS; |
|
82 | 83 | gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_IE; |
|
83 | 84 | } |
|
85 | #endif | |
|
84 | 86 | |
|
85 | 87 | void timer_stop(unsigned char timer) |
|
86 | 88 | { |
|
87 | 89 | /** This function stops a GPTIMER timer. |
|
88 | 90 | * |
|
89 | 91 | * @param gptimer_regs points to the APB registers of the GPTIMER IP core. |
|
90 | 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 | 96 | gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & GPTIMER_EN_MASK; |
|
95 | 97 | gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & GPTIMER_IE_MASK; |
|
96 | 98 | gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_CLEAR_IRQ; |
|
97 | 99 | } |
|
98 | 100 | |
|
99 | 101 | void timer_set_clock_divider(unsigned char timer, unsigned int clock_divider) |
|
100 | 102 | { |
|
101 | 103 | /** This function sets the clock divider of a GPTIMER timer. |
|
102 | 104 | * |
|
103 | 105 | * @param gptimer_regs points to the APB registers of the GPTIMER IP core. |
|
104 | 106 | * @param timer is the number of the timer in the IP core (several timers can be instantiated). |
|
105 | 107 | * @param clock_divider is the divider of the 1 MHz clock that will be configured. |
|
106 | 108 | * |
|
107 | 109 | */ |
|
108 | 110 | |
|
109 | 111 | gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz |
|
110 | 112 | } |
|
111 | 113 | |
|
112 | 114 | // WATCHDOG, this ISR should never be triggered. |
|
113 | 115 | |
|
114 | 116 | rtems_isr watchdog_isr( rtems_vector_number vector ) |
|
115 | 117 | { |
|
116 | 118 | rtems_status_code status_code; |
|
117 | 119 | |
|
118 | 120 | status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_12 ); |
|
119 | 121 | |
|
120 | 122 | PRINTF("watchdog_isr *** this is the end, exit(0)\n"); |
|
121 | 123 | |
|
122 | 124 | exit(0); |
|
123 | 125 | } |
|
124 | 126 | |
|
125 | 127 | void watchdog_configure(void) |
|
126 | 128 | { |
|
127 | 129 | /** This function configure the watchdog. |
|
128 | 130 | * |
|
129 | 131 | * @param gptimer_regs points to the APB registers of the GPTIMER IP core. |
|
130 | 132 | * @param timer is the number of the timer in the IP core (several timers can be instantiated). |
|
131 | 133 | * |
|
132 | 134 | * The watchdog is a timer provided by the GPTIMER IP core of the GRLIB. |
|
133 | 135 | * |
|
134 | 136 | */ |
|
135 | 137 | |
|
136 | 138 | LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt during configuration |
|
137 | 139 | |
|
138 | 140 | timer_configure( TIMER_WATCHDOG, CLKDIV_WATCHDOG, IRQ_SPARC_GPTIMER_WATCHDOG, watchdog_isr ); |
|
139 | 141 | |
|
140 | 142 | LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt |
|
141 | 143 | } |
|
142 | 144 | |
|
143 | 145 | void watchdog_stop(void) |
|
144 | 146 | { |
|
145 | 147 | LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt line |
|
146 | 148 | timer_stop( TIMER_WATCHDOG ); |
|
147 | 149 | LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt |
|
148 | 150 | } |
|
149 | 151 | |
|
150 | 152 | void watchdog_reload(void) |
|
151 | 153 | { |
|
152 | 154 | /** This function reloads the watchdog timer counter with the timer reload value. |
|
153 | 155 | * |
|
154 | 156 | * @param void |
|
155 | 157 | * |
|
156 | 158 | * @return void |
|
157 | 159 | * |
|
158 | 160 | */ |
|
159 | 161 | |
|
160 | 162 | gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_LD; |
|
161 | 163 | } |
|
162 | 164 | |
|
163 | 165 | void watchdog_start(void) |
|
164 | 166 | { |
|
165 | 167 | /** This function starts the watchdog timer. |
|
166 | 168 | * |
|
167 | 169 | * @param gptimer_regs points to the APB registers of the GPTIMER IP core. |
|
168 | 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 | 174 | LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); |
|
173 | 175 | |
|
174 | 176 | gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_CLEAR_IRQ; |
|
175 | 177 | gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_LD; |
|
176 | 178 | gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_EN; |
|
177 | 179 | gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_IE; |
|
178 | 180 | |
|
179 | 181 | LEON_Unmask_interrupt( IRQ_GPTIMER_WATCHDOG ); |
|
180 | 182 | |
|
181 | 183 | } |
|
182 | 184 | |
|
183 | 185 | int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register |
|
184 | 186 | { |
|
185 | 187 | struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART; |
|
186 | 188 | |
|
187 | 189 | apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE; |
|
188 | 190 | |
|
189 | 191 | return 0; |
|
190 | 192 | } |
|
191 | 193 | |
|
192 | 194 | void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value) |
|
193 | 195 | { |
|
194 | 196 | /** This function sets the scaler reload register of the apbuart module |
|
195 | 197 | * |
|
196 | 198 | * @param regs is the address of the apbuart registers in memory |
|
197 | 199 | * @param value is the value that will be stored in the scaler register |
|
198 | 200 | * |
|
199 | 201 | * The value shall be set by the software to get data on the serial interface. |
|
200 | 202 | * |
|
201 | 203 | */ |
|
202 | 204 | |
|
203 | 205 | struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs; |
|
204 | 206 | |
|
205 | 207 | apbuart_regs->scaler = value; |
|
206 | 208 | |
|
207 | 209 | BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value) |
|
208 | 210 | } |
|
209 | 211 | |
|
210 | 212 | /** |
|
211 | 213 | * @brief load_task starts and keeps the watchdog alive. |
|
212 | 214 | * @param argument |
|
213 | 215 | * @return |
|
214 | 216 | */ |
|
215 | 217 | |
|
216 | 218 | rtems_task load_task(rtems_task_argument argument) |
|
217 | 219 | { |
|
218 | 220 | BOOT_PRINTF("in LOAD *** \n") |
|
219 | 221 | |
|
220 | 222 | rtems_status_code status; |
|
221 | 223 | unsigned int i; |
|
222 | 224 | unsigned int j; |
|
223 | 225 | rtems_name name_watchdog_rate_monotonic; // name of the watchdog rate monotonic |
|
224 | 226 | rtems_id watchdog_period_id; // id of the watchdog rate monotonic period |
|
225 | 227 | |
|
226 | 228 | watchdog_period_id = RTEMS_ID_NONE; |
|
227 | 229 | |
|
228 | 230 | name_watchdog_rate_monotonic = rtems_build_name( 'L', 'O', 'A', 'D' ); |
|
229 | 231 | |
|
230 | 232 | status = rtems_rate_monotonic_create( name_watchdog_rate_monotonic, &watchdog_period_id ); |
|
231 | 233 | if( status != RTEMS_SUCCESSFUL ) { |
|
232 | 234 | PRINTF1( "in LOAD *** rtems_rate_monotonic_create failed with status of %d\n", status ) |
|
233 | 235 | } |
|
234 | 236 | |
|
235 | 237 | i = 0; |
|
236 | 238 | j = 0; |
|
237 | 239 | |
|
238 | 240 | watchdog_configure(); |
|
239 | 241 | |
|
240 | 242 | watchdog_start(); |
|
241 | 243 | |
|
242 | 244 | set_sy_lfr_watchdog_enabled( true ); |
|
243 | 245 | |
|
244 | 246 | while(1){ |
|
245 | 247 | status = rtems_rate_monotonic_period( watchdog_period_id, WATCHDOG_PERIOD ); |
|
246 | 248 | watchdog_reload(); |
|
247 | 249 | i = i + 1; |
|
248 | 250 | if ( i == WATCHDOG_LOOP_PRINTF ) |
|
249 | 251 | { |
|
250 | 252 | i = 0; |
|
251 | 253 | j = j + 1; |
|
252 | 254 | PRINTF1("%d\n", j) |
|
253 | 255 | } |
|
254 | 256 | #ifdef DEBUG_WATCHDOG |
|
255 | 257 | if (j == WATCHDOG_LOOP_DEBUG ) |
|
256 | 258 | { |
|
257 | 259 | status = rtems_task_delete(RTEMS_SELF); |
|
258 | 260 | } |
|
259 | 261 | #endif |
|
260 | 262 | } |
|
261 | 263 | } |
|
262 | 264 | |
|
263 | 265 | /** |
|
264 | 266 | * @brief hous_task produces and sends HK each seconds |
|
265 | 267 | * @param argument |
|
266 | 268 | * @return |
|
267 | 269 | */ |
|
268 | 270 | rtems_task hous_task(rtems_task_argument argument) |
|
269 | 271 | { |
|
270 | 272 | rtems_status_code status; |
|
271 | 273 | rtems_status_code spare_status; |
|
272 | 274 | rtems_id queue_id; |
|
273 | 275 | rtems_rate_monotonic_period_status period_status; |
|
274 | 276 | bool isSynchronized; |
|
275 | 277 | |
|
276 | 278 | queue_id = RTEMS_ID_NONE; |
|
277 | 279 | memset(&period_status, 0, sizeof(rtems_rate_monotonic_period_status)); |
|
278 | 280 | isSynchronized = false; |
|
279 | 281 | |
|
280 | 282 | status = get_message_queue_id_send( &queue_id ); |
|
281 | 283 | if (status != RTEMS_SUCCESSFUL) |
|
282 | 284 | { |
|
283 | 285 | PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status) |
|
284 | 286 | } |
|
285 | 287 | |
|
286 | 288 | BOOT_PRINTF("in HOUS ***\n"); |
|
287 | 289 | |
|
288 | 290 | if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) { |
|
289 | 291 | status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id ); |
|
290 | 292 | if( status != RTEMS_SUCCESSFUL ) { |
|
291 | 293 | PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status ); |
|
292 | 294 | } |
|
293 | 295 | } |
|
294 | 296 | |
|
295 | 297 | status = rtems_rate_monotonic_cancel(HK_id); |
|
296 | 298 | if( status != RTEMS_SUCCESSFUL ) { |
|
297 | 299 | PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status ); |
|
298 | 300 | } |
|
299 | 301 | else { |
|
300 | 302 | DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n"); |
|
301 | 303 | } |
|
302 | 304 | |
|
303 | 305 | // startup phase |
|
304 | 306 | status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks ); |
|
305 | 307 | status = rtems_rate_monotonic_get_status( HK_id, &period_status ); |
|
306 | 308 | DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state) |
|
307 | 309 | while( (period_status.state != RATE_MONOTONIC_EXPIRED) |
|
308 | 310 | && (isSynchronized == false) ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway |
|
309 | 311 | { |
|
310 | 312 | if ((time_management_regs->coarse_time & VAL_LFR_SYNCHRONIZED) == INT32_ALL_0) // check time synchronization |
|
311 | 313 | { |
|
312 | 314 | isSynchronized = true; |
|
313 | 315 | } |
|
314 | 316 | else |
|
315 | 317 | { |
|
316 | 318 | status = rtems_rate_monotonic_get_status( HK_id, &period_status ); |
|
317 | 319 | |
|
318 | 320 | status = rtems_task_wake_after( HK_SYNC_WAIT ); // wait HK_SYNCH_WAIT 100 ms = 10 * 10 ms |
|
319 | 321 | } |
|
320 | 322 | } |
|
321 | 323 | status = rtems_rate_monotonic_cancel(HK_id); |
|
322 | 324 | DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state) |
|
323 | 325 | |
|
324 | 326 | set_hk_lfr_reset_cause( POWER_ON ); |
|
325 | 327 | |
|
326 | 328 | while(1){ // launch the rate monotonic task |
|
327 | 329 | status = rtems_rate_monotonic_period( HK_id, HK_PERIOD ); |
|
328 | 330 | if ( status != RTEMS_SUCCESSFUL ) { |
|
329 | 331 | PRINTF1( "in HOUS *** ERR period: %d\n", status); |
|
330 | 332 | spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 ); |
|
331 | 333 | } |
|
332 | 334 | else { |
|
333 | 335 | housekeeping_packet.packetSequenceControl[BYTE_0] = (unsigned char) (sequenceCounterHK >> SHIFT_1_BYTE); |
|
334 | 336 | housekeeping_packet.packetSequenceControl[BYTE_1] = (unsigned char) (sequenceCounterHK ); |
|
335 | 337 | increment_seq_counter( &sequenceCounterHK ); |
|
336 | 338 | |
|
337 | 339 | housekeeping_packet.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES); |
|
338 | 340 | housekeeping_packet.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES); |
|
339 | 341 | housekeeping_packet.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE); |
|
340 | 342 | housekeeping_packet.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time); |
|
341 | 343 | housekeeping_packet.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE); |
|
342 | 344 | housekeeping_packet.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time); |
|
343 | 345 | |
|
344 | 346 | spacewire_update_hk_lfr_link_state( &housekeeping_packet.lfr_status_word[0] ); |
|
345 | 347 | |
|
346 | 348 | spacewire_read_statistics(); |
|
347 | 349 | |
|
348 | 350 | update_hk_with_grspw_stats(); |
|
349 | 351 | |
|
350 | 352 | set_hk_lfr_time_not_synchro(); |
|
351 | 353 | |
|
352 | 354 | housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max; |
|
353 | 355 | housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max; |
|
354 | 356 | housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max; |
|
355 | 357 | housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max; |
|
356 | 358 | housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max; |
|
357 | 359 | |
|
358 | 360 | housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare; |
|
359 | 361 | housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters; |
|
360 | 362 | get_temperatures( housekeeping_packet.hk_lfr_temp_scm ); |
|
361 | 363 | get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 ); |
|
362 | 364 | get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load ); |
|
363 | 365 | |
|
364 | 366 | hk_lfr_le_me_he_update(); |
|
365 | 367 | |
|
366 | 368 | // SEND PACKET |
|
367 | 369 | status = rtems_message_queue_send( queue_id, &housekeeping_packet, |
|
368 | 370 | PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES); |
|
369 | 371 | if (status != RTEMS_SUCCESSFUL) { |
|
370 | 372 | PRINTF1("in HOUS *** ERR send: %d\n", status) |
|
371 | 373 | } |
|
372 | 374 | } |
|
373 | 375 | } |
|
374 | 376 | |
|
375 | 377 | PRINTF("in HOUS *** deleting task\n") |
|
376 | 378 | |
|
377 | 379 | status = rtems_task_delete( RTEMS_SELF ); // should not return |
|
378 | 380 | |
|
379 | 381 | return; |
|
380 | 382 | } |
|
381 | 383 | |
|
382 | 384 | /** |
|
383 | 385 | * @brief filter is a Direct-Form-II filter implementation, mostly used to filter electric field for HK |
|
384 | 386 | * @param x, new sample |
|
385 | 387 | * @param ctx, filter context, used to store previous input and output samples |
|
386 | 388 | * @return a new filtered sample |
|
387 | 389 | */ |
|
388 | 390 | int filter( int x, filter_ctx* ctx ) |
|
389 | 391 | { |
|
390 | 392 | static const int b[NB_COEFFS][NB_COEFFS]={ {B00, B01, B02}, {B10, B11, B12}, {B20, B21, B22} }; |
|
391 | 393 | static const int a[NB_COEFFS][NB_COEFFS]={ {A00, A01, A02}, {A10, A11, A12}, {A20, A21, A22} }; |
|
392 | 394 | static const int b_gain[NB_COEFFS]={GAIN_B0, GAIN_B1, GAIN_B2}; |
|
393 | 395 | static const int a_gain[NB_COEFFS]={GAIN_A0, GAIN_A1, GAIN_A2}; |
|
394 | 396 | |
|
395 | 397 | int_fast32_t W; |
|
396 | 398 | int i; |
|
397 | 399 | |
|
398 | 400 | W = INIT_INT; |
|
399 | 401 | i = INIT_INT; |
|
400 | 402 | |
|
401 | 403 | //Direct-Form-II |
|
402 | 404 | for ( i = 0; i < NB_COEFFS; i++ ) |
|
403 | 405 | { |
|
404 | 406 | x = x << a_gain[i]; |
|
405 | 407 | W = (x - ( a[i][COEFF1] * ctx->W[i][COEFF0] ) |
|
406 | 408 | - ( a[i][COEFF2] * ctx->W[i][COEFF1] ) ) >> a_gain[i]; |
|
407 | 409 | x = ( b[i][COEFF0] * W ) |
|
408 | 410 | + ( b[i][COEFF1] * ctx->W[i][COEFF0] ) |
|
409 | 411 | + ( b[i][COEFF2] * ctx->W[i][COEFF1] ); |
|
410 | 412 | x = x >> b_gain[i]; |
|
411 | 413 | ctx->W[i][1] = ctx->W[i][0]; |
|
412 | 414 | ctx->W[i][0] = W; |
|
413 | 415 | } |
|
414 | 416 | return x; |
|
415 | 417 | } |
|
416 | 418 | |
|
417 | 419 | /** |
|
418 | 420 | * @brief avgv_task pruduces HK rate elctrical field from F3 data |
|
419 | 421 | * @param argument |
|
420 | 422 | * @return |
|
421 | 423 | */ |
|
422 | 424 | rtems_task avgv_task(rtems_task_argument argument) |
|
423 | 425 | { |
|
424 | 426 | #define MOVING_AVERAGE 16 |
|
425 | 427 | rtems_status_code status; |
|
426 | 428 | static int32_t v[MOVING_AVERAGE] = {0}; |
|
427 | 429 | static int32_t e1[MOVING_AVERAGE] = {0}; |
|
428 | 430 | static int32_t e2[MOVING_AVERAGE] = {0}; |
|
429 | 431 | static int old_v = 0; |
|
430 | 432 | static int old_e1 = 0; |
|
431 | 433 | static int old_e2 = 0; |
|
432 | 434 | int32_t current_v; |
|
433 | 435 | int32_t current_e1; |
|
434 | 436 | int32_t current_e2; |
|
435 | 437 | int32_t average_v; |
|
436 | 438 | int32_t average_e1; |
|
437 | 439 | int32_t average_e2; |
|
438 | 440 | int32_t newValue_v; |
|
439 | 441 | int32_t newValue_e1; |
|
440 | 442 | int32_t newValue_e2; |
|
441 | 443 | unsigned char k; |
|
442 | 444 | unsigned char indexOfOldValue; |
|
443 | 445 | |
|
444 | 446 | static filter_ctx ctx_v = { { {0,0,0}, {0,0,0}, {0,0,0} } }; |
|
445 | 447 | static filter_ctx ctx_e1 = { { {0,0,0}, {0,0,0}, {0,0,0} } }; |
|
446 | 448 | static filter_ctx ctx_e2 = { { {0,0,0}, {0,0,0}, {0,0,0} } }; |
|
447 | 449 | |
|
448 | 450 | BOOT_PRINTF("in AVGV ***\n"); |
|
449 | 451 | |
|
450 | 452 | if (rtems_rate_monotonic_ident( name_avgv_rate_monotonic, &AVGV_id) != RTEMS_SUCCESSFUL) { |
|
451 | 453 | status = rtems_rate_monotonic_create( name_avgv_rate_monotonic, &AVGV_id ); |
|
452 | 454 | if( status != RTEMS_SUCCESSFUL ) { |
|
453 | 455 | PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status ); |
|
454 | 456 | } |
|
455 | 457 | } |
|
456 | 458 | |
|
457 | 459 | status = rtems_rate_monotonic_cancel(AVGV_id); |
|
458 | 460 | if( status != RTEMS_SUCCESSFUL ) { |
|
459 | 461 | PRINTF1( "ERR *** in AVGV *** rtems_rate_monotonic_cancel(AVGV_id) ***code: %d\n", status ); |
|
460 | 462 | } |
|
461 | 463 | else { |
|
462 | 464 | DEBUG_PRINTF("OK *** in AVGV *** rtems_rate_monotonic_cancel(AVGV_id)\n"); |
|
463 | 465 | } |
|
464 | 466 | |
|
465 | 467 | // initialize values |
|
466 | 468 | indexOfOldValue = MOVING_AVERAGE - 1; |
|
467 | 469 | current_v = 0; |
|
468 | 470 | current_e1 = 0; |
|
469 | 471 | current_e2 = 0; |
|
470 | 472 | average_v = 0; |
|
471 | 473 | average_e1 = 0; |
|
472 | 474 | average_e2 = 0; |
|
473 | 475 | newValue_v = 0; |
|
474 | 476 | newValue_e1 = 0; |
|
475 | 477 | newValue_e2 = 0; |
|
476 | 478 | |
|
477 | 479 | k = INIT_CHAR; |
|
478 | 480 | |
|
479 | 481 | while(1) |
|
480 | 482 | { // launch the rate monotonic task |
|
481 | 483 | status = rtems_rate_monotonic_period( AVGV_id, AVGV_PERIOD ); |
|
482 | 484 | if ( status != RTEMS_SUCCESSFUL ) |
|
483 | 485 | { |
|
484 | 486 | PRINTF1( "in AVGV *** ERR period: %d\n", status); |
|
485 | 487 | } |
|
486 | 488 | else |
|
487 | 489 | { |
|
488 | 490 | current_v = waveform_picker_regs->v; |
|
489 | 491 | current_e1 = waveform_picker_regs->e1; |
|
490 | 492 | current_e2 = waveform_picker_regs->e2; |
|
491 | 493 | if ( (current_v != old_v) |
|
492 | 494 | || (current_e1 != old_e1) |
|
493 | 495 | || (current_e2 != old_e2)) |
|
494 | 496 | { |
|
495 | 497 | average_v = filter( current_v, &ctx_v ); |
|
496 | 498 | average_e1 = filter( current_e1, &ctx_e1 ); |
|
497 | 499 | average_e2 = filter( current_e2, &ctx_e2 ); |
|
498 | 500 | |
|
499 | 501 | //update int16 values |
|
500 | 502 | hk_lfr_sc_v_f3_as_int16 = (int16_t) average_v; |
|
501 | 503 | hk_lfr_sc_e1_f3_as_int16 = (int16_t) average_e1; |
|
502 | 504 | hk_lfr_sc_e2_f3_as_int16 = (int16_t) average_e2; |
|
503 | 505 | } |
|
504 | 506 | old_v = current_v; |
|
505 | 507 | old_e1 = current_e1; |
|
506 | 508 | old_e2 = current_e2; |
|
507 | 509 | } |
|
508 | 510 | } |
|
509 | 511 | |
|
510 | 512 | PRINTF("in AVGV *** deleting task\n"); |
|
511 | 513 | |
|
512 | 514 | status = rtems_task_delete( RTEMS_SELF ); // should not return |
|
513 | 515 | |
|
514 | 516 | return; |
|
515 | 517 | } |
|
516 | 518 | |
|
517 | 519 | rtems_task dumb_task( rtems_task_argument unused ) |
|
518 | 520 | { |
|
519 | 521 | /** This RTEMS taks is used to print messages without affecting the general behaviour of the software. |
|
520 | 522 | * |
|
521 | 523 | * @param unused is the starting argument of the RTEMS task |
|
522 | 524 | * |
|
523 | 525 | * The DUMB taks waits for RTEMS events and print messages depending on the incoming events. |
|
524 | 526 | * |
|
525 | 527 | */ |
|
526 | 528 | |
|
527 | 529 | unsigned int i; |
|
528 | 530 | unsigned int intEventOut; |
|
529 | 531 | unsigned int coarse_time = 0; |
|
530 | 532 | unsigned int fine_time = 0; |
|
531 | 533 | rtems_event_set event_out; |
|
532 | 534 | |
|
533 | 535 | event_out = EVENT_SETS_NONE_PENDING; |
|
534 | 536 | |
|
535 | 537 | BOOT_PRINTF("in DUMB *** \n") |
|
536 | 538 | |
|
537 | 539 | while(1){ |
|
538 | 540 | rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3 |
|
539 | 541 | | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7 |
|
540 | 542 | | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12 | RTEMS_EVENT_13 |
|
541 | 543 | | RTEMS_EVENT_14, |
|
542 | 544 | RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT |
|
543 | 545 | intEventOut = (unsigned int) event_out; |
|
544 | 546 | for ( i=0; i<NB_RTEMS_EVENTS; i++) |
|
545 | 547 | { |
|
546 | 548 | if ( ((intEventOut >> i) & 1) != 0) |
|
547 | 549 | { |
|
548 | 550 | coarse_time = time_management_regs->coarse_time; |
|
549 | 551 | fine_time = time_management_regs->fine_time; |
|