diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..ada61da2 --- /dev/null +++ b/.clang-format @@ -0,0 +1,8 @@ +--- +BasedOnStyle: Google +IndentWidth: 2 +--- +Language: Cpp +ColumnLimit: 100 +ReflowComments: true +--- diff --git a/.gitignore b/.gitignore index c51106ea..c337ab89 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ !misc/eclipse/**/.cproject !misc/eclipse/**/.project +#vscode +/.vscode + # Python __pycache__ .idea diff --git a/CMakeLists.txt b/CMakeLists.txt index 59d9d32d..585284ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,40 +13,39 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_SCRIPT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -if(TGT_BSP MATCHES "arm/q7s") - option(EIVE_BUILD_WATCHDOG "Compile the OBSW watchdog insted" OFF) - option(BUILD_Q7S_SIMPLE_MODE OFF "Simple mode with a minimal main function") -endif() -option(EIVE_BUILD_UNITTESTS "Build Catch2 unittests" OFF) option(EIVE_ADD_ETL_LIB "Add ETL library" ON) option(EIVE_ADD_JSON_LIB "Add JSON library" ON) + option(EIVE_SYSROOT_MAGIC "Perform sysroot magic which might not be necessary" OFF) +option(EIVE_CREATE_UNIQUE_OBSW_BIN "Append username to generated binary name" ON) + +set(OBSW_ADD_STAR_TRACKER 0) +set(OBSW_DEBUG_STARTRACKER 0) if(NOT FSFW_OSAL) - set(FSFW_OSAL host CACHE STRING "OS for the FSFW.") + set(FSFW_OSAL linux CACHE STRING "OS for the FSFW.") endif() -if(TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/beagleboneblack") - option(LINUX_CROSS_COMPILE ON) +if(TGT_BSP) + if(TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/beagleboneblack") + option(LINUX_CROSS_COMPILE ON) + option(EIVE_BUILD_GPSD_GPS_HANDLER "Build GPSD dependent GPS Handler" OFF) + elseif(TGT_BSP MATCHES "arm/q7s") + option(EIVE_BUILD_GPSD_GPS_HANDLER "Build GPSD dependent GPS Handler" ON) + endif() endif() # Perform steps like loading toolchain files where applicable. include(${CMAKE_SCRIPT_PATH}/PreProjectConfig.cmake) pre_project_config() -if(EIVE_BUILD_WATCHDOG) - set(PROJECT_NAME_TO_SET eive-watchdog) -elseif(EIVE_BUILD_UNITTESTS) - set(PROJECT_NAME_TO_SET eive-unittest) -elseif(TGT_BSP MATCHES "arm/q7s") - set(PROJECT_NAME_TO_SET eive-obsw-$ENV{USERNAME}) -else() - set(PROJECT_NAME_TO_SET eive-obsw) -endif() +# Check whether the user has already installed Catch2 first. This has to come before +# the project call. We could also exlcude doing this when the Q7S primary OBSW is built.. +find_package(Catch2 3 CONFIG QUIET) # Project Name -project(${PROJECT_NAME_TO_SET} ASM C CXX) +project(eive-obsw) ################################################################################ # Pre-Sources preparation @@ -57,8 +56,12 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) # Set names and variables -set(TARGET_NAME ${CMAKE_PROJECT_NAME}) +set(OBSW_NAME ${CMAKE_PROJECT_NAME}) +set(WATCHDOG_NAME eive-watchdog) +set(SIMPLE_OBSW_NAME eive-simple) +set(UNITTEST_NAME eive-unittest) set(LIB_FSFW_NAME fsfw) +set(LIB_EIVE_MISSION eive-mission) set(LIB_ETL_NAME etl) set(LIB_CSP_NAME libcsp) set(LIB_LWGPS_NAME lwgps) @@ -66,12 +69,12 @@ set(LIB_ARCSEC wire) set(THIRD_PARTY_FOLDER thirdparty) set(LIB_CXX_FS -lstdc++fs) set(LIB_CATCH2 Catch2) +set(LIB_GPS gps) set(LIB_JSON_NAME nlohmann_json::nlohmann_json) # Set path names set(FSFW_PATH fsfw) -set(MISSION_PATH mission) -set(TEST_PATH test/testtasks) +set(TEST_PATH test) set(UNITTEST_PATH unittest) set(LINUX_PATH linux) set(COMMON_PATH common) @@ -79,6 +82,7 @@ set(WATCHDOG_PATH watchdog) set(COMMON_CONFIG_PATH ${COMMON_PATH}/config) set(UNITTEST_CFG_PATH ${UNITTEST_PATH}/testcfg) +set(LIB_EIVE_MISSION_PATH mission) set(LIB_CSP_PATH ${THIRD_PARTY_FOLDER}/libcsp) set(LIB_ETL_PATH ${THIRD_PARTY_FOLDER}/etl) set(LIB_CATCH2_PATH ${THIRD_PARTY_FOLDER}/Catch2) @@ -89,13 +93,6 @@ set(LIB_JSON_PATH ${THIRD_PARTY_FOLDER}/json) set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF) set(EIVE_ADD_LINUX_FILES False) -if(EIVE_BUILD_UNITTESTS) -endif() - -if(FSFW_ADD_UNITTESTS) - set(CATCH2_TARGET Catch2) -endif() - # Analyse different OS and architecture/target options, determine BSP_PATH, # display information about compiler etc. include (${CMAKE_SCRIPT_PATH}/HardwareOsPreConfig.cmake) @@ -103,7 +100,8 @@ pre_source_hw_os_config() if(TGT_BSP) if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "arm/raspberrypi" - OR TGT_BSP MATCHES "arm/beagleboneblack" + OR TGT_BSP MATCHES "arm/beagleboneblack" OR TGT_BSP MATCHES "arm/egse" + OR TGT_BSP MATCHES "arm/te0720-1cfa" ) set(FSFW_CONFIG_PATH "linux/fsfwconfig") if(NOT BUILD_Q7S_SIMPLE_MODE) @@ -113,11 +111,19 @@ if(TGT_BSP) endif() endif() - if(TGT_BSP MATCHES "arm/raspberrypi") + if(TGT_BSP MATCHES "arm/raspberrypi" ) # Used by configure file set(RASPBERRY_PI ON) set(FSFW_HAL_ADD_RASPBERRY_PI ON) endif() + + if(TGT_BSP MATCHES "arm/egse") + # Used by configure file + set(EGSE ON) + set(FSFW_HAL_LINUX_ADD_LIBGPIOD OFF) + set(OBSW_ADD_STAR_TRACKER 1) + set(OBSW_DEBUG_STARTRACKER 1) + endif() if(TGT_BSP MATCHES "arm/beagleboneblack") # Used by configure file @@ -128,29 +134,28 @@ if(TGT_BSP) # Used by configure file set(XIPHOS_Q7S ON) endif() + + if(TGT_BSP MATCHES "arm/te0720-1cfa") + set(TE0720_1CFA ON) + endif() else() # Required by FSFW library set(FSFW_CONFIG_PATH "${BSP_PATH}/fsfwconfig") endif() -if(EIVE_BUILD_UNITTESTS) - # configure_file(${UNITTEST_CFG_PATH}/TestsConfig.h.in TestsConfig.h) - # set(FSFW_CONFIG_PATH ${UNITTEST_CFG_PATH}) -endif() # Configuration files -if(NOT EIVE_BUILD_WATCHDOG) - configure_file(${COMMON_CONFIG_PATH}/commonConfig.h.in commonConfig.h) - configure_file(${FSFW_CONFIG_PATH}/FSFWConfig.h.in FSFWConfig.h) - configure_file(${FSFW_CONFIG_PATH}/OBSWConfig.h.in OBSWConfig.h) - if(TGT_BSP MATCHES "arm/q7s") - configure_file(${BSP_PATH}/boardconfig/q7sConfig.h.in q7sConfig.h) - elseif(TGT_BSP MATCHES "arm/raspberrypi") - configure_file(${BSP_PATH}/boardconfig/rpiConfig.h.in rpiConfig.h) - endif() +configure_file(${COMMON_CONFIG_PATH}/commonConfig.h.in commonConfig.h) +configure_file(${FSFW_CONFIG_PATH}/FSFWConfig.h.in FSFWConfig.h) +configure_file(${FSFW_CONFIG_PATH}/OBSWConfig.h.in OBSWConfig.h) +if(TGT_BSP MATCHES "arm/q7s") + configure_file(${BSP_PATH}/boardconfig/q7sConfig.h.in q7sConfig.h) +elseif(TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/egse") + configure_file(${BSP_PATH}/boardconfig/rpiConfig.h.in rpiConfig.h) endif() + configure_file(${WATCHDOG_PATH}/watchdogConf.h.in watchdogConf.h) # Set common config path for FSFW @@ -163,8 +168,95 @@ set(FSFW_ADDITIONAL_INC_PATHS # Executable and Sources ################################################################################ -# Add executable -add_executable(${TARGET_NAME}) +#global compiler options need to be set before adding executables +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + add_compile_options( + "-Wall" + "-Wextra" + "-Wimplicit-fallthrough=1" + "-Wno-unused-parameter" + "-Wno-psabi" + "-Wduplicated-cond" # check for duplicate conditions + "-Wduplicated-branches" # check for duplicate branches + "-Wlogical-op" # Search for bitwise operations instead of logical + "-Wnull-dereference" # Search for NULL dereference + "-Wundef" # Warn if undefind marcos are used + "-Wformat=2" # Format string problem detection + "-Wformat-overflow=2" # Formatting issues in printf + "-Wformat-truncation=2" # Formatting issues in printf + "-Wformat-security" # Search for dangerous printf operations + "-Wstrict-overflow=3" # Warn if integer overflows might happen + "-Warray-bounds=2" # Some array bounds violations will be found + "-Wshift-overflow=2" # Search for bit left shift overflows ( General information @@ -37,7 +40,7 @@ Target systems: relevant pages. The most recent datasheet can be found [here](https://trac2.xiphos.ca/manual/wiki/Q7RevB/UserManual). * Linux OS built with Yocto 2.5 - * Linux Kernel https://github.com/XiphosSystemsCorp/linux-xlnx.git . EIVE version can be found + * [Linux Kernel](https://github.com/XiphosSystemsCorp/linux-xlnx.git) . EIVE version can be found [here](https://github.com/spacefisch/linux-xlnx) . Pre-compiled files can be found [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/q7s-linux-components&fileid=777299). * Q7S base project can be found [here](https://egit.irs.uni-stuttgart.de/eive/q7s-base) @@ -104,7 +107,7 @@ When using Windows, run theses steps in MSYS2. ```sh mkdir build-Debug-Q7S && cd build-Debug-Q7S - cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug -DOS_FSFW=linux .. + cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug .. cmake --build . -j ``` @@ -119,8 +122,7 @@ When using Windows, run theses steps in MSYS2. This will invoke a Python script which in turn invokes CMake with the correct arguments to configure CMake for Q7S cross-compilation. - You can build the hosted variant of the OBSW by replacing `-DOS_FSFW=linux` with - `-DOS_FSFW=host`. There are also different values for `-DTGT_BSP` to build for the Raspberry Pi + There are also different values for `-DTGT_BSP` to build for the Raspberry Pi or the Beagle Bone Black: `arm/raspberrypi` and `arm/beagleboneblack`. 5. Build the software with @@ -159,38 +161,45 @@ automatically. ### Q7S OBSW +The EIVE OBSW is the default target if no target is specified. + ```sh mkdir build-Debug-Q7S && cd build-Debug-Q7S -cmake -DTGT_BSP=arm/q7s -DFSFW_OSAL=linux -DCMAKE_BUILD_TYPE=Debug .. +cmake -DTGT_BSP=arm/q7s -DCMAKE_BUILD_TYPE=Debug .. cmake --build . -j ``` ### Q7S Watchdog +To build the EIVE watchdog, the corresponding target must be specified in the build command. +The configure steps do not need to be repeated if the folder has already been configured. + ```sh -mkdir build-Debug-Q7S && cd build-Debug-Q7S -cmake -DTGT_BSP=arm/q7s -DFSFW_OSAL=linux -DEIVE_BUILD_WATCHDOG=ON -DCMAKE_BUILD_TYPE=Debug .. -cmake --build . -j +mkdir build-Debug-Watchdog && cd build-Debug-Watchdog +cmake -DTGT_BSP=arm/q7s -DCMAKE_BUILD_TYPE=Debug .. +cmake --build . --target eive-watchdog -j ``` ### Hosted -You can also replace `linux` by `host` for this command to build on Windows or for generic OSes +You can also use the FSFW OSAL `host` to build on Windows or for generic OSes. +Note: Currently this is not supported. ```sh mkdir build-Debug-Host && cd build-Debug-Host -cmake -DFSFW_OSAL=linux -DCMAKE_BUILD_TYPE=Debug .. +cmake -DFSFW_OSAL=host -DCMAKE_BUILD_TYPE=Debug .. cmake --build . -j ``` ### Unittests -You can also replace `linux` by `host` for this command to build on Windows +To build the unittests, the corresponding target must be specified in the build command. +The configure steps do not need to be repeated if the folder has already been configured. ```sh mkdir build-Debug-Unittest && cd build-Debug-Unittest -cmake -DFSFW_OSAL=linux -DEIVE_BUILD_UNITTESTS=ON .. -cmake --build . -j +cmake .. +cmake --build . --target eive-unittests -j ``` ## Connect to EIVE flatsat @@ -376,20 +385,7 @@ more recent disitributions anymore. ## Installing toolchain without Vivado You can download the toolchains for Windows and Linux -[from the EIVE cloud](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files?dir=/EIVE_IRS/Software/tools&fileid=831898). - -If `wget` is available (e.g. MinGW64), you can use the following command to download the -toolchain for Windows - -```sh -wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/rfoaistRd67yBbH/download/gcc-arm-linux-gnueabi-win.zip -``` - -or the following command for Linux (could be useful for CI/CD) - -```sh -wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/MRaeA2XnMXpZ5Pp/download/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz -``` +[from the EIVE cloud](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/tools). ## Installing CMake and MSYS2 on Windows @@ -433,12 +429,24 @@ Beagle Bone Black for download here Download it and unzip it somewhere in the Xilinx installation folder. You can use the following command if `wget` can be used or for CI/CD: -``` -wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/agnJGYeRf6fw2ci/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz +```sh +wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/SyXpdBBQX32xPgE/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz ``` Then, create a new environmental variables `Q7S_SYSROOT` and set it to the local system root path. +### Updating system root for CI + +If the system root is updated, it needs to be manually updated on the buggy file server. +If access on `buggy.irs.uni-stuttgart.de` is possible with `ssh` and the rootfs in the cloud +[was updated](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/rootfs&fileid=831849) +as well, you can update the rootfs like this: + +```sh +cd /var/www/eive/tools +wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/SyXpdBBQX32xPgE/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz +``` + ## Setting up UNIX environment for real-time functionalities Please note that on most UNIX environments (e.g. Ubuntu), the real time functionalities @@ -1045,26 +1053,7 @@ cat file.bin | hexdump -v -n X ## Preparation of a fresh rootfs and SD card -This section summarizes important changes between a fresh rootfs and the current -EIVE implementation - -### rootfs - -- Mount point `/mnt/sd0` created for SD card 0. Created with `mkdir` -- Mount point `/mnt/sd1` created for SD card 1. Created with `mkdir` -- Folder `scripts` in `/home/root` folder. -- `scripts` folder currently contains a few shell helper scripts -- Folder `profile.d` in `/etc` folder which contains the `path-set.sh` script - which is sourced at software startup -- Library `libwire.so` in `/usr/lib` folder - -### SD Cards - -- Folder `bin` for binaries, for example the OBSW -- Folder `misc` for miscellaneous files. Contains `ls` for directory listings -- Folder `tc` for telecommands -- Folder `tm` for telemetry -- Folder `xdi` for XDI components (e.g. for firmware or device tree updates) +See [q7s-package repository README](https://egit.irs.uni-stuttgart.de/eive/q7s-package) # Running cppcheck on the Software @@ -1112,7 +1101,7 @@ The [TCF agent](https://wiki.eclipse.org/TCF) can be used to perform remote debu 1. Install the TCF agent plugin in Eclipse from the [releases](https://www.eclipse.org/tcf/downloads.php). Go to Help → Install New Software and use the download page, for - example https://download.eclipse.org/tools/tcf/releases/1.6/1.6.2/ to search for the plugin and install it. + example https://download.eclipse.org/tools/tcf/releases/1.7/1.7.0/ to search for the plugin and install it. You can find the newest version [here](https://www.eclipse.org/tcf/downloads.php) 2. Go to Window → Perspective → Open Perspective and open the **Target Explorer Perspective**. Here, the Q7S should show up if the local port forwarding was set up as explained previously. @@ -1151,6 +1140,38 @@ sudo apt-get install gpiod libgpiod-dev to install the required GPIO libraries before cloning the system root folder. +# Running OBSW on EGSE +The EGSE is a test system from arcsec build arround a raspberry pi 4 to test the star tracker. The IP address of the EGSE (raspberry pi) is 192.168.18.31. An ssh session can be opened with +```` +ssh pi@192.168.18.31 +```` +Password: raspberry + +To run the obsw perform the following steps: +1. Build the cmake EGSE Configuration + * the sysroots for the EGSE can be found [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/egse&fileid=1190471) + * toolchain for linux host can be downloaded from [here](https://github.com/Pro/raspi-toolchain) + * toolchain for windows host from [here](https://gnutoolchains.com/raspberry/) (the raspios-buster-armhf toolchain is the right one for the EGSE) +2. Disable the ser2net systemd service on the EGSE +````sh +$ sudo systemctl stop ser2net.service +```` +3. Power on the star tracker by running +````sh +$ ~/powerctrl/enable0.sh` +```` +4. Run portforwarding script for tmtc tcp connection and tcf agent on host PC +````sh +$ ./scripts/egse-port.sh +```` +5. The star tracker can be powered off by running +````sh +$ ~/powerctrl/disable0.sh +```` + +# Manually preparing sysroots to compile gpsd +Copy all header files from [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/gpsd&fileid=1189985) to the /usr/include directory and all static libraries to /usr/lib. + # Flight Software Framework (FSFW) An EIVE fork of the FSFW is submodules into this repository. @@ -1170,3 +1191,15 @@ git merge upstream/master Alternatively, changes from other upstreams (forks) and branches can be merged like that in the same way. + +# Coding Style +* the formatting is based on the clang-format tools +## Setting up eclipse auto-fromatter with clang-format +1. Help → Install New Software → Add +2. In location insert the link http://www.cppstyle.com/luna +3. The software package CppStyle should now be available for installation +4. On windows download the clang-formatting tools from https://llvm.org/builds/. On linux clang-format can be installed with the package manager. +5. Navigate to Preferences → C/C++ → CppStyle +6. Insert the path to the clang-format executable +7. Under C/C++ → Code Style → Formatter, change the formatter to CppStyle (clang-format) +8. Code can now be formatted with the clang tool by using the key combination Ctrl + Shift + f diff --git a/SDK.log b/SDK.log new file mode 100644 index 00000000..d90ec6b5 --- /dev/null +++ b/SDK.log @@ -0,0 +1,5 @@ +10:00:08 INFO : Registering command handlers for SDK TCF services +10:00:10 INFO : Launching XSCT server: xsct.bat -interactive C:\Users\EIVE_Reinraumrechner\eive-software\eive-obsw\temp_xsdb_launch_script.tcl +10:00:16 INFO : XSCT server has started successfully. +10:00:22 INFO : Successfully done setting XSCT server connection channel +10:00:22 INFO : Successfully done setting SDK workspace diff --git a/linux/archive/gpio/CMakeLists.txt b/archive/gpio/CMakeLists.txt similarity index 100% rename from linux/archive/gpio/CMakeLists.txt rename to archive/gpio/CMakeLists.txt diff --git a/archive/gpio/GpioCookie.cpp b/archive/gpio/GpioCookie.cpp new file mode 100644 index 00000000..b1bb2db4 --- /dev/null +++ b/archive/gpio/GpioCookie.cpp @@ -0,0 +1,32 @@ +#include "GpioCookie.h" + +#include + +GpioCookie::GpioCookie() {} + +ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpioBase* gpioConfig) { + if (gpioConfig == nullptr) { + sif::debug << "GpioCookie::addGpio: gpioConfig is nullpointer" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + auto gpioMapIter = gpioMap.find(gpioId); + if (gpioMapIter == gpioMap.end()) { + auto statusPair = gpioMap.emplace(gpioId, gpioConfig); + if (statusPair.second == false) { +#if FSFW_VERBOSE_LEVEL >= 1 + sif::error << "GpioCookie::addGpio: Failed to add GPIO " << gpioId << " to GPIO map" + << std::endl; +#endif + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; + } +#if FSFW_VERBOSE_LEVEL >= 1 + sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map " << std::endl; +#endif + return HasReturnvaluesIF::RETURN_FAILED; +} + +GpioMap GpioCookie::getGpioMap() const { return gpioMap; } + +GpioCookie::~GpioCookie() {} diff --git a/linux/archive/gpio/GpioCookie.h b/archive/gpio/GpioCookie.h similarity index 64% rename from linux/archive/gpio/GpioCookie.h rename to archive/gpio/GpioCookie.h index 3f8531ee..9295a4ac 100644 --- a/linux/archive/gpio/GpioCookie.h +++ b/archive/gpio/GpioCookie.h @@ -1,11 +1,12 @@ #ifndef LINUX_GPIO_GPIOCOOKIE_H_ #define LINUX_GPIO_GPIOCOOKIE_H_ -#include "GpioIF.h" -#include "gpioDefinitions.h" #include #include +#include "GpioIF.h" +#include "gpioDefinitions.h" + /** * @brief Cookie for the GpioIF. Allows the GpioIF to determine which * GPIOs to initialize and whether they should be configured as in- or @@ -16,24 +17,23 @@ * * @author J. Meier */ -class GpioCookie: public CookieIF { -public: +class GpioCookie : public CookieIF { + public: + GpioCookie(); - GpioCookie(); + virtual ~GpioCookie(); - virtual ~GpioCookie(); + ReturnValue_t addGpio(gpioId_t gpioId, GpioBase* gpioConfig); + /** + * @brief Get map with registered GPIOs. + */ + GpioMap getGpioMap() const; - ReturnValue_t addGpio(gpioId_t gpioId, GpioBase* gpioConfig); - /** - * @brief Get map with registered GPIOs. - */ - GpioMap getGpioMap() const; - -private: - /** - * Returns a copy of the internal GPIO map. - */ - GpioMap gpioMap; + private: + /** + * Returns a copy of the internal GPIO map. + */ + GpioMap gpioMap; }; #endif /* LINUX_GPIO_GPIOCOOKIE_H_ */ diff --git a/archive/gpio/GpioIF.h b/archive/gpio/GpioIF.h new file mode 100644 index 00000000..045af556 --- /dev/null +++ b/archive/gpio/GpioIF.h @@ -0,0 +1,54 @@ +#ifndef LINUX_GPIO_GPIOIF_H_ +#define LINUX_GPIO_GPIOIF_H_ + +#include +#include + +#include "gpioDefinitions.h" + +class GpioCookie; + +/** + * @brief This class defines the interface for objects requiring the control + * over GPIOs. + * @author J. Meier + */ +class GpioIF : public HasReturnvaluesIF { + public: + virtual ~GpioIF(){}; + + /** + * @brief Called by the GPIO using object. + * @param cookie Cookie specifying informations of the GPIOs required + * by a object. + */ + virtual ReturnValue_t addGpios(GpioCookie* cookie) = 0; + + /** + * @brief By implementing this function a child must provide the + * functionality to pull a certain GPIO to high logic level. + * + * @param gpioId A unique number which specifies the GPIO to drive. + * @return Returns RETURN_OK for success. This should never return RETURN_FAILED. + */ + virtual ReturnValue_t pullHigh(gpioId_t gpioId) = 0; + + /** + * @brief By implementing this function a child must provide the + * functionality to pull a certain GPIO to low logic level. + * + * @param gpioId A unique number which specifies the GPIO to drive. + */ + virtual ReturnValue_t pullLow(gpioId_t gpioId) = 0; + + /** + * @brief This function requires a child to implement the functionality to read the state of + * an ouput or input gpio. + * + * @param gpioId A unique number which specifies the GPIO to read. + * @param gpioState State of GPIO will be written to this pointer. + */ + virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0; +}; + +#endif /* LINUX_GPIO_GPIOIF_H_ */ diff --git a/archive/gpio/LinuxLibgpioIF.cpp b/archive/gpio/LinuxLibgpioIF.cpp new file mode 100644 index 00000000..e5dcc1f2 --- /dev/null +++ b/archive/gpio/LinuxLibgpioIF.cpp @@ -0,0 +1,295 @@ +#include "LinuxLibgpioIF.h" + +#include +#include +#include +#include + +#include + +#include "GpioCookie.h" + +LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) { + struct gpiod_chip* chip = gpiod_chip_open_by_label("/amba_pl/gpio@42030000"); + + sif::debug << chip->name << std::endl; +} + +LinuxLibgpioIF::~LinuxLibgpioIF() {} + +ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) { + ReturnValue_t result; + if (gpioCookie == nullptr) { + sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl; + return RETURN_FAILED; + } + + GpioMap mapToAdd = gpioCookie->getGpioMap(); + + /* Check whether this ID already exists in the map and remove duplicates */ + result = checkForConflicts(mapToAdd); + if (result != RETURN_OK) { + return result; + } + + result = configureGpios(mapToAdd); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + + /* Register new GPIOs in gpioMap */ + gpioMap.insert(mapToAdd.begin(), mapToAdd.end()); + + return RETURN_OK; +} + +ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { + for (auto& gpioConfig : mapToAdd) { + switch (gpioConfig.second->gpioType) { + case (gpio::GpioTypes::NONE): { + return GPIO_INVALID_INSTANCE; + } + case (gpio::GpioTypes::GPIOD_REGULAR): { + GpiodRegular* regularGpio = dynamic_cast(gpioConfig.second); + if (regularGpio == nullptr) { + return GPIO_INVALID_INSTANCE; + } + configureRegularGpio(gpioConfig.first, regularGpio); + break; + } + case (gpio::GpioTypes::CALLBACK): { + auto gpioCallback = dynamic_cast(gpioConfig.second); + if (gpioCallback->callback == nullptr) { + return GPIO_INVALID_INSTANCE; + } + gpioCallback->callback(gpioConfig.first, gpio::GpioOperation::WRITE, + gpioCallback->initValue, gpioCallback->callbackArgs); + } + } + } + return RETURN_OK; +} + +ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular* regularGpio) { + std::string chipname; + unsigned int lineNum; + struct gpiod_chip* chip; + gpio::Direction direction; + std::string consumer; + struct gpiod_line* lineHandle; + int result = 0; + + chipname = regularGpio->chipname; + chip = gpiod_chip_open_by_name(chipname.c_str()); + if (!chip) { + sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip " << chipname + << ". Gpio ID: " << gpioId << std::endl; + return RETURN_FAILED; + } + + lineNum = regularGpio->lineNum; + lineHandle = gpiod_chip_get_line(chip, lineNum); + if (!lineHandle) { + sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line for GPIO with id " << gpioId + << std::endl; + gpiod_chip_close(chip); + return RETURN_FAILED; + } + + direction = regularGpio->direction; + consumer = regularGpio->consumer; + /* Configure direction and add a description to the GPIO */ + switch (direction) { + case (gpio::OUT): { + result = gpiod_line_request_output(lineHandle, consumer.c_str(), regularGpio->initValue); + if (result < 0) { + sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " << lineNum + << " from GPIO instance with ID: " << gpioId << std::endl; + gpiod_line_release(lineHandle); + return RETURN_FAILED; + } + break; + } + case (gpio::IN): { + result = gpiod_line_request_input(lineHandle, consumer.c_str()); + if (result < 0) { + sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " << lineNum + << " from GPIO instance with ID: " << gpioId << std::endl; + gpiod_line_release(lineHandle); + return RETURN_FAILED; + } + break; + } + default: { + sif::error << "LinuxLibgpioIF::configureGpios: Invalid direction specified" << std::endl; + return GPIO_INVALID_INSTANCE; + } + } + /** + * Write line handle to GPIO configuration instance so it can later be used to set or + * read states of GPIOs. + */ + regularGpio->lineHandle = lineHandle; + return RETURN_OK; +} + +ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) { + gpioMapIter = gpioMap.find(gpioId); + if (gpioMapIter == gpioMap.end()) { + sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl; + return UNKNOWN_GPIO_ID; + } + + if (gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { + return driveGpio(gpioId, dynamic_cast(gpioMapIter->second), 1); + } else { + auto gpioCallback = dynamic_cast(gpioMapIter->second); + if (gpioCallback->callback == nullptr) { + return GPIO_INVALID_INSTANCE; + } + gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE, 1, + gpioCallback->callbackArgs); + } + return GPIO_TYPE_FAILURE; +} + +ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) { + gpioMapIter = gpioMap.find(gpioId); + if (gpioMapIter == gpioMap.end()) { + sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl; + return UNKNOWN_GPIO_ID; + } + + if (gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { + return driveGpio(gpioId, dynamic_cast(gpioMapIter->second), 0); + } else { + auto gpioCallback = dynamic_cast(gpioMapIter->second); + if (gpioCallback->callback == nullptr) { + return GPIO_INVALID_INSTANCE; + } + gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE, 0, + gpioCallback->callbackArgs); + } + return GPIO_TYPE_FAILURE; +} + +ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, GpiodRegular* regularGpio, + unsigned int logicLevel) { + if (regularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + + int result = gpiod_line_set_value(regularGpio->lineHandle, logicLevel); + if (result < 0) { + sif::warning << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId + << " to logic level " << logicLevel << std::endl; + return DRIVE_GPIO_FAILURE; + } + + return RETURN_OK; +} + +ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { + gpioMapIter = gpioMap.find(gpioId); + if (gpioMapIter == gpioMap.end()) { + sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl; + return UNKNOWN_GPIO_ID; + } + + if (gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { + GpiodRegular* regularGpio = dynamic_cast(gpioMapIter->second); + if (regularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + *gpioState = gpiod_line_get_value(regularGpio->lineHandle); + } else { + } + + return RETURN_OK; +} + +ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd) { + ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + for (auto& gpioConfig : mapToAdd) { + switch (gpioConfig.second->gpioType) { + case (gpio::GpioTypes::GPIOD_REGULAR): { + auto regularGpio = dynamic_cast(gpioConfig.second); + if (regularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + /* Check for conflicts and remove duplicates if necessary */ + result = checkForConflictsRegularGpio(gpioConfig.first, regularGpio, mapToAdd); + if (result != HasReturnvaluesIF::RETURN_OK) { + status = result; + } + break; + } + case (gpio::GpioTypes::CALLBACK): { + auto callbackGpio = dynamic_cast(gpioConfig.second); + if (callbackGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + /* Check for conflicts and remove duplicates if necessary */ + result = checkForConflictsCallbackGpio(gpioConfig.first, callbackGpio, mapToAdd); + if (result != HasReturnvaluesIF::RETURN_OK) { + status = result; + } + break; + } + default: { + } + } + } + return status; +} + +ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck, + GpiodRegular* gpioToCheck, + GpioMap& mapToAdd) { + /* Cross check with private map */ + gpioMapIter = gpioMap.find(gpioIdToCheck); + if (gpioMapIter != gpioMap.end()) { + if (gpioMapIter->second->gpioType != gpio::GpioTypes::GPIOD_REGULAR) { + sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different " + "GPIO type" + << gpioIdToCheck << ". Removing duplicate." << std::endl; + mapToAdd.erase(gpioIdToCheck); + return HasReturnvaluesIF::RETURN_OK; + } + auto ownRegularGpio = dynamic_cast(gpioMapIter->second); + if (ownRegularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + + /* Remove element from map to add because a entry for this GPIO + already exists */ + sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition" + << " detected. Duplicate will be removed from map to add." << std::endl; + mapToAdd.erase(gpioIdToCheck); + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t LinuxLibgpioIF::checkForConflictsCallbackGpio(gpioId_t gpioIdToCheck, + GpioCallback* callbackGpio, + GpioMap& mapToAdd) { + /* Cross check with private map */ + gpioMapIter = gpioMap.find(gpioIdToCheck); + if (gpioMapIter != gpioMap.end()) { + if (gpioMapIter->second->gpioType != gpio::GpioTypes::CALLBACK) { + sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different " + "GPIO type" + << gpioIdToCheck << ". Removing duplicate." << std::endl; + mapToAdd.erase(gpioIdToCheck); + return HasReturnvaluesIF::RETURN_OK; + } + + /* Remove element from map to add because a entry for this GPIO + already exists */ + sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition" + << " detected. Duplicate will be removed from map to add." << std::endl; + mapToAdd.erase(gpioIdToCheck); + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/archive/gpio/LinuxLibgpioIF.h b/archive/gpio/LinuxLibgpioIF.h new file mode 100644 index 00000000..1c974efb --- /dev/null +++ b/archive/gpio/LinuxLibgpioIF.h @@ -0,0 +1,75 @@ +#ifndef LINUX_GPIO_LINUXLIBGPIOIF_H_ +#define LINUX_GPIO_LINUXLIBGPIOIF_H_ + +#include +#include +#include + +class GpioCookie; + +/** + * @brief This class implements the GpioIF for a linux based system. The + * implementation is based on the libgpiod lib which requires linux 4.8 + * or higher. + * @note The Petalinux SDK from Xilinx supports libgpiod since Petalinux + * 2019.1. + */ +class LinuxLibgpioIF : public GpioIF, public SystemObject { + public: + static const uint8_t gpioRetvalId = CLASS_ID::LINUX_LIBGPIO_IF; + + static constexpr ReturnValue_t UNKNOWN_GPIO_ID = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 1); + static constexpr ReturnValue_t DRIVE_GPIO_FAILURE = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 2); + static constexpr ReturnValue_t GPIO_TYPE_FAILURE = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 3); + static constexpr ReturnValue_t GPIO_INVALID_INSTANCE = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4); + + LinuxLibgpioIF(object_id_t objectId); + virtual ~LinuxLibgpioIF(); + + ReturnValue_t addGpios(GpioCookie* gpioCookie) override; + ReturnValue_t pullHigh(gpioId_t gpioId) override; + ReturnValue_t pullLow(gpioId_t gpioId) override; + ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override; + + private: + /* Holds the information and configuration of all used GPIOs */ + GpioMap gpioMap; + GpioMapIter gpioMapIter; + + /** + * @brief This functions drives line of a GPIO specified by the GPIO ID. + * + * @param gpioId The GPIO ID of the GPIO to drive. + * @param logiclevel The logic level to set. O or 1. + */ + ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio, unsigned int logiclevel); + + ReturnValue_t configureRegularGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio); + + /** + * @brief This function checks if GPIOs are already registered and whether + * there exists a conflict in the GPIO configuration. E.g. the + * direction. + * + * @param mapToAdd The GPIOs which shall be added to the gpioMap. + * + * @return RETURN_OK if successful, otherwise RETURN_FAILED + */ + ReturnValue_t checkForConflicts(GpioMap& mapToAdd); + + ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegular* regularGpio, + GpioMap& mapToAdd); + ReturnValue_t checkForConflictsCallbackGpio(gpioId_t gpiodId, GpioCallback* regularGpio, + GpioMap& mapToAdd); + + /** + * @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd. + */ + ReturnValue_t configureGpios(GpioMap& mapToAdd); +}; + +#endif /* LINUX_GPIO_LINUXLIBGPIOIF_H_ */ diff --git a/archive/gpio/gpioDefinitions.h b/archive/gpio/gpioDefinitions.h new file mode 100644 index 00000000..46050d12 --- /dev/null +++ b/archive/gpio/gpioDefinitions.h @@ -0,0 +1,83 @@ +#ifndef LINUX_GPIO_GPIODEFINITIONS_H_ +#define LINUX_GPIO_GPIODEFINITIONS_H_ + +#include +#include + +using gpioId_t = uint16_t; + +namespace gpio { + +enum class Levels : uint8_t { LOW = 0, HIGH = 1 }; + +enum class Direction : uint8_t { IN = 0, OUT = 1 }; + +enum class GpioOperation { READ, WRITE }; + +enum class GpioTypes { NONE, GPIOD_REGULAR, CALLBACK }; + +static constexpr gpioId_t NO_GPIO = -1; +} // namespace gpio + +/** + * @brief Struct containing information about the GPIO to use. This is + * required by the libgpiod to access and drive a GPIO. + * @param chipname String of the chipname specifying the group which contains the GPIO to + * access. E.g. gpiochip0. To detect names of GPIO groups run gpiodetect on + * the linux command line. + * @param lineNum The offset of the GPIO within the GPIO group. + * @param consumer Name of the consumer. Simply a description of the GPIO configuration. + * @param direction Specifies whether the GPIO should be used as in- or output. + * @param initValue Defines the initial state of the GPIO when configured as output. + * Only required for output GPIOs. + * @param lineHandle The handle returned by gpiod_chip_get_line will be later written to this + * pointer. + */ +class GpioBase { + public: + GpioBase() = default; + + GpioBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction, int initValue) + : gpioType(gpioType), consumer(consumer), direction(direction), initValue(initValue) {} + + virtual ~GpioBase(){}; + + /* Can be used to cast GpioBase to a concrete child implementation */ + gpio::GpioTypes gpioType = gpio::GpioTypes::NONE; + std::string consumer; + gpio::Direction direction = gpio::Direction::IN; + int initValue = 0; +}; + +class GpiodRegular : public GpioBase { + public: + GpiodRegular() + : GpioBase(gpio::GpioTypes::GPIOD_REGULAR, std::string(), gpio::Direction::IN, 0){}; + + GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_, + gpio::Direction direction_, int initValue_) + : GpioBase(gpio::GpioTypes::GPIOD_REGULAR, consumer_, direction_, initValue_), + chipname(chipname_), + lineNum(lineNum_) {} + std::string chipname; + int lineNum = 0; + struct gpiod_line* lineHandle = nullptr; +}; + +class GpioCallback : public GpioBase { + public: + GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_, + void (*callback)(gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args), + void* callbackArgs) + : GpioBase(gpio::GpioTypes::CALLBACK, consumer, direction_, initValue_), + callback(callback), + callbackArgs(callbackArgs) {} + + void (*callback)(gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args) = nullptr; + void* callbackArgs = nullptr; +}; + +using GpioMap = std::unordered_map; +using GpioMapIter = GpioMap::iterator; + +#endif /* LINUX_GPIO_GPIODEFINITIONS_H_ */ diff --git a/archive/tmtc/CCSDSIPCoreBridge.cpp b/archive/tmtc/CCSDSIPCoreBridge.cpp new file mode 100644 index 00000000..607ccebd --- /dev/null +++ b/archive/tmtc/CCSDSIPCoreBridge.cpp @@ -0,0 +1,128 @@ +#include +#include +#include + +CCSDSIPCoreBridge::CCSDSIPCoreBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId, object_id_t tcStoreId, + LinuxLibgpioIF* gpioComIF, std::string uioPtme, + gpioId_t papbBusyId, gpioId_t papbEmptyId) + : TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId), + gpioComIF(gpioComIF), + uioPtme(uioPtme), + papbBusyId(papbBusyId), + papbEmptyId(papbEmptyId) {} + +CCSDSIPCoreBridge::~CCSDSIPCoreBridge() {} + +ReturnValue_t CCSDSIPCoreBridge::initialize() { + ReturnValue_t result = TmTcBridge::initialize(); + + fd = open("/dev/uio0", O_RDWR); + if (fd < 1) { + sif::debug << "CCSDSIPCoreBridge::initialize: Invalid UIO device file" << std::endl; + return RETURN_FAILED; + } + + /** + * Map uio device in virtual address space + * PROT_WRITE: Map uio device in writable only mode + */ + ptmeBaseAddress = + static_cast(mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); + + if (ptmeBaseAddress == MAP_FAILED) { + sif::error << "CCSDSIPCoreBridge::initialize: Failed to map uio address" << std::endl; + return RETURN_FAILED; + } + + return result; +} + +ReturnValue_t CCSDSIPCoreBridge::handleTm() { +#if OBSW_TEST_CCSDS_PTME == 1 + return sendTestFrame(); +#else + return TmTcBridge::handleTm(); +#endif +} + +ReturnValue_t CCSDSIPCoreBridge::sendTm(const uint8_t* data, size_t dataLen) { + if (pollPapbBusySignal() == RETURN_OK) { + startPacketTransfer(); + } + + for (size_t idx = 0; idx < dataLen; idx++) { + if (pollPapbBusySignal() == RETURN_OK) { + *(ptmeBaseAddress + PTME_DATA_REG_OFFSET) = static_cast(*(data + idx)); + } else { + sif::debug << "CCSDSIPCoreBridge::sendTm: Only written " << idx - 1 << " of " << dataLen + << " data" << std::endl; + return RETURN_FAILED; + } + } + + if (pollPapbBusySignal() == RETURN_OK) { + endPacketTransfer(); + } + return RETURN_OK; +} + +void CCSDSIPCoreBridge::startPacketTransfer() { *ptmeBaseAddress = PTME_CONFIG_START; } + +void CCSDSIPCoreBridge::endPacketTransfer() { *ptmeBaseAddress = PTME_CONFIG_END; } + +ReturnValue_t CCSDSIPCoreBridge::pollPapbBusySignal() { + int papbBusyState = 0; + ReturnValue_t result = RETURN_OK; + + /** Check if PAPB interface is ready to receive data */ + result = gpioComIF->readGpio(papbBusyId, &papbBusyState); + if (result != RETURN_OK) { + sif::debug << "CCSDSIPCoreBridge::pollPapbBusySignal: Failed to read papb busy signal" + << std::endl; + return RETURN_FAILED; + } + if (!papbBusyState) { + sif::debug << "CCSDSIPCoreBridge::pollPapbBusySignal: PAPB busy" << std::endl; + return PAPB_BUSY; + } + + return RETURN_OK; +} + +void CCSDSIPCoreBridge::isPtmeBufferEmpty() { + ReturnValue_t result = RETURN_OK; + int papbEmptyState = 1; + + result = gpioComIF->readGpio(papbEmptyId, &papbEmptyState); + + if (result != RETURN_OK) { + sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Failed to read papb empty signal" + << std::endl; + return; + } + + if (papbEmptyState == 1) { + sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Buffer is empty" << std::endl; + } else { + sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Buffer is not empty" << std::endl; + } + return; +} + +ReturnValue_t CCSDSIPCoreBridge::sendTestFrame() { + /** Size of one complete transfer frame data field amounts to 1105 bytes */ + uint8_t testPacket[1105]; + + /** Fill one test packet */ + for (int idx = 0; idx < 1105; idx++) { + testPacket[idx] = static_cast(idx & 0xFF); + } + + ReturnValue_t result = sendTm(testPacket, 1105); + if (result != RETURN_OK) { + return result; + } + + return RETURN_OK; +} diff --git a/archive/tmtc/CCSDSIPCoreBridge.h b/archive/tmtc/CCSDSIPCoreBridge.h new file mode 100644 index 00000000..074769c4 --- /dev/null +++ b/archive/tmtc/CCSDSIPCoreBridge.h @@ -0,0 +1,129 @@ +#ifndef MISSION_OBC_CCSDSIPCOREBRIDGE_H_ +#define MISSION_OBC_CCSDSIPCOREBRIDGE_H_ + +#include +#include +#include + +#include + +#include "OBSWConfig.h" + +/** + * @brief This class handles the interfacing to the telemetry (PTME) and telecommand (PDEC) IP + * cores responsible for the CCSDS encoding and decoding. The IP cores are implemented + * on the programmable logic and are accessible through the linux UIO driver. + */ +class CCSDSIPCoreBridge : public TmTcBridge { + public: + /** + * @brief Constructor + * + * @param objectId + * @param tcDestination + * @param tmStoreId + * @param tcStoreId + * @param uioPtme Name of the uio device file which provides access to the PTME IP Core. + * @param papbBusyId The ID of the GPIO which is connected to the PAPBBusy_N signal of the + * PTME IP Core. A low logic level indicates the PTME is not ready to + * receive more data. + * @param papbEmptyId The ID of the GPIO which is connected to the PAPBEmpty signal of the + * PTME IP Core. The signal is high when there are no packets in the + * external buffer memory (BRAM). + */ + CCSDSIPCoreBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, + object_id_t tcStoreId, LinuxLibgpioIF* gpioComIF, std::string uioPtme, + gpioId_t papbBusyId, gpioId_t papbEmptyId); + virtual ~CCSDSIPCoreBridge(); + + ReturnValue_t initialize() override; + + protected: + /** + * Overwriting this function to provide the capability of testing the PTME IP Core + * implementation. + */ + virtual ReturnValue_t handleTm() override; + + virtual ReturnValue_t sendTm(const uint8_t* data, size_t dataLen) override; + + private: + static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_IP_CORE_BRIDGE; + + static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0); + + /** Size of mapped address space. 4k (minimal size of pl device) */ + // static const int MAP_SIZE = 0xFA0; + static const int MAP_SIZE = 0x1000; + + /** + * Configuration bits: + * bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00 + * bit[2]: Set this bit to 1 to abort a transfered packet + * bit[3]: Signals to PTME the start of a new telemetry packet + */ + static const uint32_t PTME_CONFIG_START = 0x8; + + /** + * Writing this word to the ptme base address signals to the PTME that a complete tm packet has + * been transferred. + */ + static const uint32_t PTME_CONFIG_END = 0x0; + + /** + * Writing to this offset within the PTME memory space will insert data for encoding to the + * PTME IP core. + * The address offset is 0x400 (= 4 * 256) + */ + static const int PTME_DATA_REG_OFFSET = 256; + + LinuxLibgpioIF* gpioComIF = nullptr; + + /** The uio device file related to the PTME IP Core */ + std::string uioPtme; + + /** Pulled to low when PTME not ready to receive data */ + gpioId_t papbBusyId = gpio::NO_GPIO; + + /** High when externally buffer memory of PTME is empty */ + gpioId_t papbEmptyId = gpio::NO_GPIO; + + /** The file descriptor of the UIO driver */ + int fd; + + uint32_t* ptmeBaseAddress = nullptr; + + /** + * @brief This function sends the config byte to the PTME IP Core to initiate a packet + * transfer. + */ + void startPacketTransfer(); + + /** + * @brief This function sends the config byte to the PTME IP Core to signal the end of a + * packet transfer. + */ + void endPacketTransfer(); + + /** + * @brief This function reads the papb busy signal indicating whether the PAPB interface is + * ready to receive more data or not. PAPB is ready when PAPB_Busy_N == '1'. + * + * @return RETURN_OK when ready to receive data else PAPB_BUSY. + */ + ReturnValue_t pollPapbBusySignal(); + + /** + * @brief This function can be used for debugging to check wheter there are packets in + * the packet buffer of the PTME or not. + */ + void isPtmeBufferEmpty(); + + /** + * @brief This function sends a complete telemetry transfer frame data field (1105 bytes) + * to the input of the PTME IP Core. Can be used to test the implementation. + */ + ReturnValue_t sendTestFrame(); +}; + +#endif /* MISSION_OBC_CCSDSIPCOREBRIDGE_H_ */ diff --git a/automation/Dockerfile-q7s b/automation/Dockerfile similarity index 67% rename from automation/Dockerfile-q7s rename to automation/Dockerfile index 21b56439..63592c77 100644 --- a/automation/Dockerfile-q7s +++ b/automation/Dockerfile @@ -2,7 +2,9 @@ FROM ubuntu:focal RUN apt-get update RUN apt-get --yes upgrade -RUN apt-get --yes install cmake libgpiod-dev xz-utils nano curl +#tzdata is a dependency, won't install otherwise +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get --yes install cmake libgpiod-dev xz-utils nano curl git gcc g++ lcov valgrind libgps-dev # Q7S root filesystem, required for cross-compilation. RUN mkdir -p /usr/rootfs; \ @@ -14,6 +16,5 @@ RUN mkdir -p /usr/tools; \ curl https://buggy.irs.uni-stuttgart.de/eive/tools/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.gz \ | tar -xz -C /usr/tools - -ENV Q7S_SYSROOT="/usr/rootfs/cortexa9hf-neon-xiphos-linux-gnueabi" +ENV ZYNQ_7020_SYSROOT="/usr/rootfs/cortexa9hf-neon-xiphos-linux-gnueabi" ENV PATH=$PATH:"/usr/tools/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin" diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile index 7b184280..ee50924a 100644 --- a/automation/Jenkinsfile +++ b/automation/Jenkinsfile @@ -1,48 +1,36 @@ pipeline { - agent any - stages { - stage('Build Container') { - when { - changeset "automation/Dockerfile-q7s" - branch 'develop' - } - steps { - sh 'docker build -t eive-fsw-build-q7s:gcc8 - < automation/Dockerfile-q7s' - - } + environment { + BUILDDIR_Q7 = 'build_q7' + BUILDDIR_LINUX = 'build_linux' + } + agent { + docker { + image 'eive-obsw-ci:d3' + args '--sysctl fs.mqueue.msg_max=100' } + } + stages { stage('Clean') { - when { - anyOf { - changelog 'cleanCI' - changeset '*.cmake' - changeset 'CMakeLists.txt' - } - } steps { - sh 'rm -rf build-q7s-debug' + sh 'rm -rf $BUILDDIR_Q7' + sh 'rm -rf $BUILDDIR_LINUX' } } stage('Build Q7S') { - agent { - docker { - image 'eive-fsw-build-q7s:gcc8' - reuseNode true - } - } steps { - dir('build-q7s-debug') { - sh 'cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug -DFSFW_OSAL=linux ..' - sh 'cmake --build . -j' + dir(BUILDDIR_Q7) { + sh 'cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug ..' + sh 'cmake --build . -j4' } } } - stage('Deploy') { - when { - tag 'v*.*.*' - } + stage('Unittests') { steps { - sh 'echo Deploying' + dir(BUILDDIR_LINUX) { + sh 'cmake ..' + sh 'cmake --build . -t eive-unittest -j4' + sh './eive-unittest' + } } } } diff --git a/bsp_egse/CMakeLists.txt b/bsp_egse/CMakeLists.txt new file mode 100644 index 00000000..cb02f937 --- /dev/null +++ b/bsp_egse/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${OBSW_NAME} PUBLIC + InitMission.cpp + main.cpp + ObjectFactory.cpp +) + +add_subdirectory(boardconfig) diff --git a/bsp_egse/InitMission.cpp b/bsp_egse/InitMission.cpp new file mode 100644 index 00000000..d6b192c2 --- /dev/null +++ b/bsp_egse/InitMission.cpp @@ -0,0 +1,192 @@ +#include "InitMission.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "OBSWConfig.h" +#include "ObjectFactory.h" +#include "objects/systemObjectList.h" +#include "pollingsequence/pollingSequenceFactory.h" + +ServiceInterfaceStream sif::debug("DEBUG"); +ServiceInterfaceStream sif::info("INFO"); +ServiceInterfaceStream sif::warning("WARNING"); +ServiceInterfaceStream sif::error("ERROR"); + +ObjectManagerIF* objectManager = nullptr; + +void initmission::initMission() { + sif::info << "Make sure the systemd service ser2net on the egse has been stopped " + << "(alias stop-ser2net)" << std::endl; + sif::info << "Make sure the power lines of the star tracker have been enabled " + << "(alias enable-startracker)" << std::endl; + sif::info << "Building global objects.." << std::endl; + /* Instantiate global object manager and also create all objects */ + ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr); + sif::info << "Initializing all objects.." << std::endl; + ObjectManager::instance()->initialize(); + + /* This function creates and starts all tasks */ + initTasks(); +} + +void initmission::initTasks() { + TaskFactory* factory = TaskFactory::instance(); + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if (factory == nullptr) { + /* Should never happen ! */ + return; + } +#if OBSW_PRINT_MISSED_DEADLINES == 1 + void (*missedDeadlineFunc)(void) = TaskFactory::printMissedDeadline; +#else + void (*missedDeadlineFunc)(void) = nullptr; +#endif + + /* TMTC Distribution */ + PeriodicTaskIF* tmtcDistributor = factory->createPeriodicTask( + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = tmtcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + result = tmtcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + result = tmtcDistributor->addComponent(objects::TM_FUNNEL); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + + PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask( + "TMTC_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component TMTC Bridge failed" << std::endl; + } + PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( + "TMTC_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component TMTC Polling failed" << std::endl; + } + + /* PUS Services */ + std::vector pusTasks; + createPusTasks(*factory, missedDeadlineFunc, pusTasks); + + std::vector pstTasks; + FixedTimeslotTaskIF* pst = factory->createFixedTimeslotTask( + "STAR_TRACKER_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc); + result = pst::pstUart(pst); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; + } + pstTasks.push_back(pst); + + PeriodicTaskIF* strHelperTask = factory->createPeriodicTask( + "STR_HELPER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = strHelperTask->addComponent(objects::STR_HELPER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("STR_HELPER", objects::STR_HELPER); + } + pstTasks.push_back(strHelperTask); + + auto taskStarter = [](std::vector& taskVector, std::string name) { + for (const auto& task : taskVector) { + if (task != nullptr) { + task->startTask(); + } else { + sif::error << "Task in vector " << name << " is invalid!" << std::endl; + } + } + }; + + sif::info << "Starting tasks.." << std::endl; + tmtcDistributor->startTask(); + tmtcBridgeTask->startTask(); + tmtcPollingTask->startTask(); + + taskStarter(pstTasks, "PST Tasks"); + taskStarter(pusTasks, "PUS Tasks"); + + sif::info << "Tasks started.." << std::endl; +} + +void initmission::createPusTasks(TaskFactory& factory, + TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + PeriodicTaskIF* pusVerification = factory.createPeriodicTask( + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + taskVec.push_back(pusVerification); + + PeriodicTaskIF* pusEvents = factory.createPeriodicTask( + "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); + } + result = pusEvents->addComponent(objects::EVENT_MANAGER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER); + } + taskVec.push_back(pusEvents); + + PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask( + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); + } + result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); + } + taskVec.push_back(pusHighPrio); + + PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask( + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS3", objects::PUS_SERVICE_3_HOUSEKEEPING); + } + taskVec.push_back(pusMedPrio); + + PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); + } + result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("INT_ERR_RPRT", objects::INTERNAL_ERROR_REPORTER); + } + taskVec.push_back(pusLowPrio); +} diff --git a/bsp_egse/InitMission.h b/bsp_egse/InitMission.h new file mode 100644 index 00000000..c3ba58ec --- /dev/null +++ b/bsp_egse/InitMission.h @@ -0,0 +1,21 @@ +#ifndef BSP_LINUX_INITMISSION_H_ +#define BSP_LINUX_INITMISSION_H_ + +#include + +#include "fsfw/tasks/Typedef.h" + +class PeriodicTaskIF; +class TaskFactory; + +namespace initmission { +void initMission(); +void initTasks(); + +void createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec); +void createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec); +}; // namespace initmission + +#endif /* BSP_LINUX_INITMISSION_H_ */ diff --git a/bsp_egse/ObjectFactory.cpp b/bsp_egse/ObjectFactory.cpp new file mode 100644 index 00000000..8d5e3416 --- /dev/null +++ b/bsp_egse/ObjectFactory.cpp @@ -0,0 +1,48 @@ +#include "ObjectFactory.h" + +#include +#include +#include + +#include "OBSWConfig.h" +#include "busConf.h" +#include "fsfw/datapoollocal/LocalDataPoolManager.h" +#include "fsfw/tmtcpacket/pus/tm.h" +#include "fsfw/tmtcservices/CommandingServiceBase.h" +#include "fsfw/tmtcservices/PusServiceBase.h" +#include "linux/devices/devicedefinitions/StarTrackerDefinitions.h" +#include "linux/devices/startracker/StarTrackerHandler.h" +#include "mission/core/GenericFactory.h" +#include "mission/utility/TmFunnel.h" +#include "objects/systemObjectList.h" +#include "tmtc/apid.h" +#include "tmtc/pusIds.h" + +void Factory::setStaticFrameworkObjectIds() { + PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; + PusServiceBase::packetDestination = objects::TM_FUNNEL; + + CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; + CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; + + TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; + TmFunnel::storageDestination = objects::NO_OBJECT; + + VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION; + TmPacketBase::timeStamperId = objects::TIME_STAMPER; +} + +void ObjectFactory::produce(void* args) { + Factory::setStaticFrameworkObjectIds(); + ObjectFactory::produceGenericObjects(); + + UartCookie* starTrackerCookie = + new UartCookie(objects::STAR_TRACKER, egse::STAR_TRACKER_UART, UartModes::NON_CANONICAL, + uart::STAR_TRACKER_BAUD, startracker::MAX_FRAME_SIZE * 2 + 2); + new UartComIF(objects::UART_COM_IF); + starTrackerCookie->setNoFixedSizeReply(); + StrHelper* strHelper = new StrHelper(objects::STR_HELPER); + StarTrackerHandler* starTrackerHandler = new StarTrackerHandler( + objects::STAR_TRACKER, objects::UART_COM_IF, starTrackerCookie, strHelper); + starTrackerHandler->setStartUpImmediately(); +} diff --git a/bsp_egse/ObjectFactory.h b/bsp_egse/ObjectFactory.h new file mode 100644 index 00000000..b24dd321 --- /dev/null +++ b/bsp_egse/ObjectFactory.h @@ -0,0 +1,8 @@ +#ifndef BSP_LINUX_OBJECTFACTORY_H_ +#define BSP_LINUX_OBJECTFACTORY_H_ + +namespace ObjectFactory { +void produce(void* args); +}; // namespace ObjectFactory + +#endif /* BSP_LINUX_OBJECTFACTORY_H_ */ diff --git a/bsp_egse/boardconfig/CMakeLists.txt b/bsp_egse/boardconfig/CMakeLists.txt new file mode 100644 index 00000000..f9136e3e --- /dev/null +++ b/bsp_egse/boardconfig/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${OBSW_NAME} PRIVATE + print.c +) + +target_include_directories(${OBSW_NAME} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/bsp_egse/boardconfig/busConf.h b/bsp_egse/boardconfig/busConf.h new file mode 100644 index 00000000..4df55edc --- /dev/null +++ b/bsp_egse/boardconfig/busConf.h @@ -0,0 +1,8 @@ +#ifndef BSP_EGSE_BOARDCONFIG_BUSCONF_H_ +#define BSP_EGSE_BOARDCONFIG_BUSCONF_H_ + +namespace egse { +static constexpr char STAR_TRACKER_UART[] = "/dev/serial0"; +} + +#endif /* BSP_EGSE_BOARDCONFIG_BUSCONF_H_ */ diff --git a/bsp_egse/boardconfig/etl_profile.h b/bsp_egse/boardconfig/etl_profile.h new file mode 100644 index 00000000..54aca344 --- /dev/null +++ b/bsp_egse/boardconfig/etl_profile.h @@ -0,0 +1,38 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2019 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ +#ifndef __ETL_PROFILE_H__ +#define __ETL_PROFILE_H__ + +#define ETL_CHECK_PUSH_POP + +#define ETL_CPP11_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 + +#endif diff --git a/bsp_egse/boardconfig/gcov.h b/bsp_egse/boardconfig/gcov.h new file mode 100644 index 00000000..80acdd86 --- /dev/null +++ b/bsp_egse/boardconfig/gcov.h @@ -0,0 +1,15 @@ +#ifndef LINUX_GCOV_H_ +#define LINUX_GCOV_H_ +#include + +#ifdef GCOV +extern "C" void __gcov_flush(); +#else +void __gcov_flush() { + sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if " + "coverage information is desired.\n" + << std::flush; +} +#endif + +#endif /* LINUX_GCOV_H_ */ diff --git a/bsp_egse/boardconfig/print.c b/bsp_egse/boardconfig/print.c new file mode 100644 index 00000000..5b3a0f91 --- /dev/null +++ b/bsp_egse/boardconfig/print.c @@ -0,0 +1,10 @@ +#include +#include + +void printChar(const char* character, bool errStream) { + if (errStream) { + putc(*character, stderr); + return; + } + putc(*character, stdout); +} diff --git a/bsp_egse/boardconfig/print.h b/bsp_egse/boardconfig/print.h new file mode 100644 index 00000000..8e7e2e5d --- /dev/null +++ b/bsp_egse/boardconfig/print.h @@ -0,0 +1,8 @@ +#ifndef HOSTED_BOARDCONFIG_PRINT_H_ +#define HOSTED_BOARDCONFIG_PRINT_H_ + +#include + +void printChar(const char* character, bool errStream); + +#endif /* HOSTED_BOARDCONFIG_PRINT_H_ */ diff --git a/bsp_egse/boardconfig/rpiConfig.h.in b/bsp_egse/boardconfig/rpiConfig.h.in new file mode 100644 index 00000000..af4f0dd2 --- /dev/null +++ b/bsp_egse/boardconfig/rpiConfig.h.in @@ -0,0 +1,6 @@ +#ifndef BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ +#define BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ + +#include + +#endif /* BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ */ diff --git a/bsp_egse/main.cpp b/bsp_egse/main.cpp new file mode 100644 index 00000000..75fb4f19 --- /dev/null +++ b/bsp_egse/main.cpp @@ -0,0 +1,28 @@ +#include + +#include "InitMission.h" +#include "OBSWConfig.h" +#include "OBSWVersion.h" +#include "fsfw/tasks/TaskFactory.h" +#include "fsfw/version.h" + +/** + * @brief This is the main program entry point for the egse (raspberry pi 4) + * @return + */ +int main(void) { + std::cout << "-- EIVE OBSW --" << std::endl; + std::cout << "-- Compiled for EGSE from Arcsec" + << " --" << std::endl; + std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << "." + << SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << FSFW_REVISION + << "--" << std::endl; + std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; + + initmission::initMission(); + + for (;;) { + /* Suspend main thread by sleeping it. */ + TaskFactory::delayTask(5000); + } +} diff --git a/bsp_hosted/CMakeLists.txt b/bsp_hosted/CMakeLists.txt index b8a09a88..7787cf7e 100644 --- a/bsp_hosted/CMakeLists.txt +++ b/bsp_hosted/CMakeLists.txt @@ -1,4 +1,4 @@ -target_sources(${TARGET_NAME} PUBLIC +target_sources(${OBSW_NAME} PUBLIC InitMission.cpp main.cpp ObjectFactory.cpp diff --git a/bsp_hosted/InitMission.cpp b/bsp_hosted/InitMission.cpp index ed6b8820..0ca59db5 100644 --- a/bsp_hosted/InitMission.cpp +++ b/bsp_hosted/InitMission.cpp @@ -1,20 +1,19 @@ #include "InitMission.h" -#include "ObjectFactory.h" #include - +#include #include #include #include -#include #include #include #include - #include #include +#include "ObjectFactory.h" + #ifdef LINUX ServiceInterfaceStream sif::debug("DEBUG"); ServiceInterfaceStream sif::info("INFO"); @@ -27,133 +26,132 @@ ServiceInterfaceStream sif::warning("WARNING", true); ServiceInterfaceStream sif::error("ERROR", true, false, true); #endif -ObjectManagerIF *objectManager = nullptr; +ObjectManagerIF* objectManager = nullptr; void initmission::initMission() { - sif::info << "Building global objects.." << std::endl; - /* Instantiate global object manager and also create all objects */ - ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr); - sif::info << "Initializing all objects.." << std::endl; - ObjectManager::instance()->initialize(); + sif::info << "Building global objects.." << std::endl; + /* Instantiate global object manager and also create all objects */ + ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr); + sif::info << "Initializing all objects.." << std::endl; + ObjectManager::instance()->initialize(); - /* This function creates and starts all tasks */ - initTasks(); + /* This function creates and starts all tasks */ + initTasks(); } void initmission::initTasks() { - TaskFactory* factory = TaskFactory::instance(); - if(factory == nullptr) { - /* Should never happen ! */ - return; - } + TaskFactory* factory = TaskFactory::instance(); + if (factory == nullptr) { + /* Should never happen ! */ + return; + } #if OBSW_PRINT_MISSED_DEADLINES == 1 - void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline; + void (*missedDeadlineFunc)(void) = TaskFactory::printMissedDeadline; #else - void (*missedDeadlineFunc) (void) = nullptr; + void (*missedDeadlineFunc)(void) = nullptr; #endif - /* TMTC Distribution */ - PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( - "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - ReturnValue_t result = tmTcDistributor->addComponent( - objects::CCSDS_PACKET_DISTRIBUTOR); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - result = tmTcDistributor->addComponent(objects::TM_FUNNEL); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Object add component failed" << std::endl; - } + /* TMTC Distribution */ + PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + ReturnValue_t result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + result = tmTcDistributor->addComponent(objects::TM_FUNNEL); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } - /* UDP bridge */ - PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask( - "TMTC_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Add component UDP Unix Bridge failed" << std::endl; - } - PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( - "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Add component UDP Polling failed" << std::endl; - } + /* UDP bridge */ + PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask( + "TMTC_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component UDP Unix Bridge failed" << std::endl; + } + PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( + "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component UDP Polling failed" << std::endl; + } - /* PUS Services */ - PeriodicTaskIF* pusVerification = factory->createPeriodicTask( - "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } + /* PUS Services */ + PeriodicTaskIF* pusVerification = factory->createPeriodicTask( + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } - PeriodicTaskIF* pusEvents = factory->createPeriodicTask( - "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); - if(result != HasReturnvaluesIF::RETURN_OK){ - initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING); - } + PeriodicTaskIF* pusEvents = factory->createPeriodicTask( + "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING); + } - PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( - "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); - } - result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); - } + PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); + } + result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); + } - PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( - "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); - result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT); - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); - } + PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); + } - PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( - "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); - result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); - } + PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); + } - PeriodicTaskIF* testTask = factory->createPeriodicTask( - "TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + PeriodicTaskIF* testTask = factory->createPeriodicTask( + "TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); #if OBSW_ADD_TEST_CODE == 1 - result = testTask->addComponent(objects::TEST_TASK); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); - } + result = testTask->addComponent(objects::TEST_TASK); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + } #endif /* OBSW_ADD_TEST_CODE == 1 */ - sif::info << "Starting tasks.." << std::endl; - tmTcDistributor->startTask(); - tmtcBridgeTask->startTask(); - tmtcPollingTask->startTask(); + sif::info << "Starting tasks.." << std::endl; + tmTcDistributor->startTask(); + tmtcBridgeTask->startTask(); + tmtcPollingTask->startTask(); - pusVerification->startTask(); - pusEvents->startTask(); - pusHighPrio->startTask(); - pusMedPrio->startTask(); - pusLowPrio->startTask(); + pusVerification->startTask(); + pusEvents->startTask(); + pusHighPrio->startTask(); + pusMedPrio->startTask(); + pusLowPrio->startTask(); #if OBSW_ADD_TEST_CODE == 1 - testTask->startTask(); + testTask->startTask(); #endif /* OBSW_ADD_TEST_CODE == 1 */ - sif::info << "Tasks started.." << std::endl; + sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_hosted/InitMission.h b/bsp_hosted/InitMission.h index 01c72008..507de592 100644 --- a/bsp_hosted/InitMission.h +++ b/bsp_hosted/InitMission.h @@ -4,6 +4,6 @@ namespace initmission { void initMission(); void initTasks(); -}; +}; // namespace initmission #endif /* BSP_LINUX_INITMISSION_H_ */ diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index 6803ace4..e1be7588 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -1,14 +1,14 @@ #include "ObjectFactory.h" -#include "OBSWConfig.h" + +#include +#include +#include +#include #include #include #include -#include -#include - -#include -#include +#include "OBSWConfig.h" #if OBSW_USE_TMTC_TCP_BRIDGE == 0 #include "fsfw/osal/common/UdpTcPollingTask.h" @@ -20,29 +20,28 @@ #include - #if OBSW_ADD_TEST_CODE == 1 #include #endif -void Factory::setStaticFrameworkObjectIds(){ - PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; - PusServiceBase::packetDestination = objects::TM_FUNNEL; +void Factory::setStaticFrameworkObjectIds() { + PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; + PusServiceBase::packetDestination = objects::TM_FUNNEL; - CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; - CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; + CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; + CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; - TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; - // No storage object for now. - TmFunnel::storageDestination = objects::NO_OBJECT; + TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; + // No storage object for now. + TmFunnel::storageDestination = objects::NO_OBJECT; - VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION; - TmPacketBase::timeStamperId = objects::TIME_STAMPER; + VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION; + TmPacketBase::timeStamperId = objects::TIME_STAMPER; } -void ObjectFactory::produce(void* args){ - Factory::setStaticFrameworkObjectIds(); - ObjectFactory::produceGenericObjects(); +void ObjectFactory::produce(void* args) { + Factory::setStaticFrameworkObjectIds(); + ObjectFactory::produceGenericObjects(); - new TestTask(objects::TEST_TASK); + new TestTask(objects::TEST_TASK); } diff --git a/bsp_hosted/ObjectFactory.h b/bsp_hosted/ObjectFactory.h index feaba70e..b042f9dc 100644 --- a/bsp_hosted/ObjectFactory.h +++ b/bsp_hosted/ObjectFactory.h @@ -1,10 +1,9 @@ #ifndef BSP_LINUX_OBJECTFACTORY_H_ #define BSP_LINUX_OBJECTFACTORY_H_ - namespace ObjectFactory { - void setStatics(); - void produce(void* args); -}; +void setStatics(); +void produce(void* args); +}; // namespace ObjectFactory #endif /* BSP_LINUX_OBJECTFACTORY_H_ */ diff --git a/bsp_hosted/boardconfig/CMakeLists.txt b/bsp_hosted/boardconfig/CMakeLists.txt index c32b326d..81c8c93d 100644 --- a/bsp_hosted/boardconfig/CMakeLists.txt +++ b/bsp_hosted/boardconfig/CMakeLists.txt @@ -1,8 +1,8 @@ -target_sources(${TARGET_NAME} PRIVATE +target_sources(${OBSW_NAME} PRIVATE print.c ) -target_include_directories(${TARGET_NAME} PUBLIC +target_include_directories(${OBSW_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/bsp_hosted/boardconfig/etl_profile.h b/bsp_hosted/boardconfig/etl_profile.h index c35ffb46..54aca344 100644 --- a/bsp_hosted/boardconfig/etl_profile.h +++ b/bsp_hosted/boardconfig/etl_profile.h @@ -32,7 +32,7 @@ SOFTWARE. #define ETL_CHECK_PUSH_POP -#define ETL_CPP11_SUPPORTED 1 -#define ETL_NO_NULLPTR_SUPPORT 0 +#define ETL_CPP11_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 #endif diff --git a/bsp_hosted/boardconfig/gcov.h b/bsp_hosted/boardconfig/gcov.h index 491d24c6..80acdd86 100644 --- a/bsp_hosted/boardconfig/gcov.h +++ b/bsp_hosted/boardconfig/gcov.h @@ -6,8 +6,9 @@ extern "C" void __gcov_flush(); #else void __gcov_flush() { - sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if " - "coverage information is desired.\n" << std::flush; + sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if " + "coverage information is desired.\n" + << std::flush; } #endif diff --git a/bsp_hosted/boardconfig/print.c b/bsp_hosted/boardconfig/print.c index f35f9447..9653fe5f 100644 --- a/bsp_hosted/boardconfig/print.c +++ b/bsp_hosted/boardconfig/print.c @@ -3,13 +3,9 @@ #include void printChar(const char* character, bool errStream) { - if(errStream) { - putc(*character, stderr); - return; - } - putc(*character, stdout); + if (errStream) { + putc(*character, stderr); + return; + } + putc(*character, stdout); } - - - - diff --git a/bsp_hosted/comIF/ArduinoComIF.cpp b/bsp_hosted/comIF/ArduinoComIF.cpp index 2db293e6..be136e45 100644 --- a/bsp_hosted/comIF/ArduinoComIF.cpp +++ b/bsp_hosted/comIF/ArduinoComIF.cpp @@ -1,376 +1,351 @@ #include "ArduinoComIF.h" -#include "ArduinoCookie.h" -#include #include +#include #include +#include "ArduinoCookie.h" + // This only works on Linux #ifdef LINUX -#include #include +#include #include #elif WIN32 -#include #include +#include #endif #include -ArduinoComIF::ArduinoComIF(object_id_t setObjectId, bool promptComIF, - const char *serialDevice): - rxBuffer(MAX_PACKET_SIZE * MAX_NUMBER_OF_SPI_DEVICES*10, true), - SystemObject(setObjectId) { +ArduinoComIF::ArduinoComIF(object_id_t setObjectId, bool promptComIF, const char *serialDevice) + : rxBuffer(MAX_PACKET_SIZE * MAX_NUMBER_OF_SPI_DEVICES * 10, true), SystemObject(setObjectId) { #ifdef LINUX - initialized = false; - serialPort = ::open("/dev/ttyUSB0", O_RDWR); + initialized = false; + serialPort = ::open("/dev/ttyUSB0", O_RDWR); - if (serialPort < 0) { - //configuration error - printf("Error %i from open: %s\n", errno, strerror(errno)); - return; - } + if (serialPort < 0) { + // configuration error + printf("Error %i from open: %s\n", errno, strerror(errno)); + return; + } - struct termios tty; - memset(&tty, 0, sizeof tty); + struct termios tty; + memset(&tty, 0, sizeof tty); - // Read in existing settings, and handle any error - if (tcgetattr(serialPort, &tty) != 0) { - printf("Error %i from tcgetattr: %s\n", errno, strerror(errno)); - return; - } + // Read in existing settings, and handle any error + if (tcgetattr(serialPort, &tty) != 0) { + printf("Error %i from tcgetattr: %s\n", errno, strerror(errno)); + return; + } - tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity - tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication - tty.c_cflag |= CS8; // 8 bits per byte - tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control - tty.c_lflag &= ~ICANON; //Disable Canonical Mode - tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars) - tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed - tty.c_cc[VTIME] = 0; // Non Blocking - tty.c_cc[VMIN] = 0; + tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity + tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication + tty.c_cflag |= CS8; // 8 bits per byte + tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control + tty.c_lflag &= ~ICANON; // Disable Canonical Mode + tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars) + tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed + tty.c_cc[VTIME] = 0; // Non Blocking + tty.c_cc[VMIN] = 0; - cfsetispeed(&tty, B9600); //Baudrate + cfsetispeed(&tty, B9600); // Baudrate - if (tcsetattr(serialPort, TCSANOW, &tty) != 0) { - //printf("Error %i from tcsetattr: %s\n", errno, strerror(errno)); - return; - } + if (tcsetattr(serialPort, TCSANOW, &tty) != 0) { + // printf("Error %i from tcsetattr: %s\n", errno, strerror(errno)); + return; + } - initialized = true; + initialized = true; #elif WIN32 - DCB serialParams = { 0 }; + DCB serialParams = {0}; - // we need to ask the COM port from the user. - if(promptComIF) { - sif::info << "Please enter the COM port (c to cancel): " << std::flush; - std::string comPort; - while(hCom == INVALID_HANDLE_VALUE) { + // we need to ask the COM port from the user. + if (promptComIF) { + sif::info << "Please enter the COM port (c to cancel): " << std::flush; + std::string comPort; + while (hCom == INVALID_HANDLE_VALUE) { + std::getline(std::cin, comPort); + if (comPort[0] == 'c') { + break; + } + const TCHAR *pcCommPort = comPort.c_str(); + hCom = CreateFileA(pcCommPort, // port name + GENERIC_READ | GENERIC_WRITE, // Read/Write + 0, // No Sharing + NULL, // No Security + OPEN_EXISTING, // Open existing port only + 0, // Non Overlapped I/O + NULL); // Null for Comm Devices - std::getline(std::cin, comPort); - if(comPort[0] == 'c') { - break; - } - const TCHAR *pcCommPort = comPort.c_str(); - hCom = CreateFileA(pcCommPort, //port name - GENERIC_READ | GENERIC_WRITE, //Read/Write - 0, // No Sharing - NULL, // No Security - OPEN_EXISTING,// Open existing port only - 0, // Non Overlapped I/O - NULL); // Null for Comm Devices + if (hCom == INVALID_HANDLE_VALUE) { + if (GetLastError() == 2) { + sif::error << "COM Port does not found!" << std::endl; + } else { + TCHAR err[128]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, sizeof(err), NULL); + // Handle the error. + sif::info << "CreateFileA Error code: " << GetLastError() << std::endl; + sif::error << err << std::flush; + } + sif::info << "Please enter a valid COM port: " << std::flush; + } + } + } - if (hCom == INVALID_HANDLE_VALUE) - { - if(GetLastError() == 2) { - sif::error << "COM Port does not found!" << std::endl; - } - else { - TCHAR err[128]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - err, sizeof(err), NULL); - // Handle the error. - sif::info << "CreateFileA Error code: " << GetLastError() - << std::endl; - sif::error << err << std::flush; - } - sif::info << "Please enter a valid COM port: " << std::flush; - } - } + serialParams.DCBlength = sizeof(serialParams); + if (baudRate == 9600) { + serialParams.BaudRate = CBR_9600; + } + if (baudRate == 115200) { + serialParams.BaudRate = CBR_115200; + } else { + serialParams.BaudRate = baudRate; + } - } + serialParams.ByteSize = 8; + serialParams.Parity = NOPARITY; + serialParams.StopBits = ONESTOPBIT; + SetCommState(hCom, &serialParams); - - serialParams.DCBlength = sizeof(serialParams); - if(baudRate == 9600) { - serialParams.BaudRate = CBR_9600; - } - if(baudRate == 115200) { - serialParams.BaudRate = CBR_115200; - } - else { - serialParams.BaudRate = baudRate; - } - - serialParams.ByteSize = 8; - serialParams.Parity = NOPARITY; - serialParams.StopBits = ONESTOPBIT; - SetCommState(hCom, &serialParams); - - COMMTIMEOUTS timeout = { 0 }; - // This will set the read operation to be blocking until data is received - // and then read continuously until there is a gap of one millisecond. - timeout.ReadIntervalTimeout = 1; - timeout.ReadTotalTimeoutConstant = 0; - timeout.ReadTotalTimeoutMultiplier = 0; - timeout.WriteTotalTimeoutConstant = 0; - timeout.WriteTotalTimeoutMultiplier = 0; - SetCommTimeouts(hCom, &timeout); - // Serial port should now be read for operations. + COMMTIMEOUTS timeout = {0}; + // This will set the read operation to be blocking until data is received + // and then read continuously until there is a gap of one millisecond. + timeout.ReadIntervalTimeout = 1; + timeout.ReadTotalTimeoutConstant = 0; + timeout.ReadTotalTimeoutMultiplier = 0; + timeout.WriteTotalTimeoutConstant = 0; + timeout.WriteTotalTimeoutMultiplier = 0; + SetCommTimeouts(hCom, &timeout); + // Serial port should now be read for operations. #endif } ArduinoComIF::~ArduinoComIF() { #ifdef LINUX - ::close(serialPort); + ::close(serialPort); #elif WIN32 - CloseHandle(hCom); + CloseHandle(hCom); #endif } -ReturnValue_t ArduinoComIF::initializeInterface(CookieIF * cookie) { - return HasReturnvaluesIF::RETURN_OK; +ReturnValue_t ArduinoComIF::initializeInterface(CookieIF *cookie) { + return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t ArduinoComIF::sendMessage(CookieIF *cookie, const uint8_t *data, - size_t len) { - ArduinoCookie *arduinoCookie = dynamic_cast(cookie); - if (arduinoCookie == nullptr) { - return INVALID_COOKIE_TYPE; - } +ReturnValue_t ArduinoComIF::sendMessage(CookieIF *cookie, const uint8_t *data, size_t len) { + ArduinoCookie *arduinoCookie = dynamic_cast(cookie); + if (arduinoCookie == nullptr) { + return INVALID_COOKIE_TYPE; + } - return sendMessage(arduinoCookie->command, arduinoCookie->address, data, - len); + return sendMessage(arduinoCookie->command, arduinoCookie->address, data, len); } -ReturnValue_t ArduinoComIF::getSendSuccess(CookieIF *cookie) { - return RETURN_OK; +ReturnValue_t ArduinoComIF::getSendSuccess(CookieIF *cookie) { return RETURN_OK; } + +ReturnValue_t ArduinoComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) { + return RETURN_OK; } -ReturnValue_t ArduinoComIF::requestReceiveMessage(CookieIF *cookie, - size_t requestLen) { - return RETURN_OK; +ReturnValue_t ArduinoComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) { + handleSerialPortRx(); + + ArduinoCookie *arduinoCookie = dynamic_cast(cookie); + if (arduinoCookie == nullptr) { + return INVALID_COOKIE_TYPE; + } + + *buffer = arduinoCookie->replyBuffer.data(); + *size = arduinoCookie->receivedDataLen; + return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t ArduinoComIF::readReceivedMessage(CookieIF *cookie, - uint8_t **buffer, size_t *size) { +ReturnValue_t ArduinoComIF::sendMessage(uint8_t command, uint8_t address, const uint8_t *data, + size_t dataLen) { + if (dataLen > UINT16_MAX) { + return TOO_MUCH_DATA; + } - handleSerialPortRx(); + // being conservative here + uint8_t sendBuffer[(dataLen + 6) * 2 + 2]; - ArduinoCookie *arduinoCookie = dynamic_cast(cookie); - if (arduinoCookie == nullptr) { - return INVALID_COOKIE_TYPE; - } + sendBuffer[0] = DleEncoder::STX_CHAR; - *buffer = arduinoCookie->replyBuffer.data(); - *size = arduinoCookie->receivedDataLen; - return HasReturnvaluesIF::RETURN_OK; -} + uint8_t *currentPosition = sendBuffer + 1; + size_t remainingLen = sizeof(sendBuffer) - 1; + size_t encodedLen = 0; -ReturnValue_t ArduinoComIF::sendMessage(uint8_t command, - uint8_t address, const uint8_t *data, size_t dataLen) { - if (dataLen > UINT16_MAX) { - return TOO_MUCH_DATA; - } + ReturnValue_t result = + DleEncoder::encode(&command, 1, currentPosition, remainingLen, &encodedLen, false); + if (result != RETURN_OK) { + return result; + } + currentPosition += encodedLen; + remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen - //being conservative here - uint8_t sendBuffer[(dataLen + 6) * 2 + 2]; + result = DleEncoder::encode(&address, 1, currentPosition, remainingLen, &encodedLen, false); + if (result != RETURN_OK) { + return result; + } + currentPosition += encodedLen; + remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen - sendBuffer[0] = DleEncoder::STX_CHAR; + uint8_t temporaryBuffer[2]; - uint8_t *currentPosition = sendBuffer + 1; - size_t remainingLen = sizeof(sendBuffer) - 1; - size_t encodedLen = 0; + // note to Lukas: yes we _could_ use Serialize here, but for 16 bit it is a bit too much... + temporaryBuffer[0] = dataLen >> 8; // we checked dataLen above + temporaryBuffer[1] = dataLen; - ReturnValue_t result = DleEncoder::encode(&command, 1, currentPosition, - remainingLen, &encodedLen, false); - if (result != RETURN_OK) { - return result; - } - currentPosition += encodedLen; - remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen + result = + DleEncoder::encode(temporaryBuffer, 2, currentPosition, remainingLen, &encodedLen, false); + if (result != RETURN_OK) { + return result; + } + currentPosition += encodedLen; + remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen - result = DleEncoder::encode(&address, 1, currentPosition, remainingLen, - &encodedLen, false); - if (result != RETURN_OK) { - return result; - } - currentPosition += encodedLen; - remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen + // encoding the actual data + result = DleEncoder::encode(data, dataLen, currentPosition, remainingLen, &encodedLen, false); + if (result != RETURN_OK) { + return result; + } + currentPosition += encodedLen; + remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen - uint8_t temporaryBuffer[2]; + uint16_t crc = CRC::crc16ccitt(&command, 1); + crc = CRC::crc16ccitt(&address, 1, crc); + // fortunately the length is still there + crc = CRC::crc16ccitt(temporaryBuffer, 2, crc); + crc = CRC::crc16ccitt(data, dataLen, crc); - //note to Lukas: yes we _could_ use Serialize here, but for 16 bit it is a bit too much... - temporaryBuffer[0] = dataLen >> 8; //we checked dataLen above - temporaryBuffer[1] = dataLen; + temporaryBuffer[0] = crc >> 8; + temporaryBuffer[1] = crc; - result = DleEncoder::encode(temporaryBuffer, 2, currentPosition, - remainingLen, &encodedLen, false); - if (result != RETURN_OK) { - return result; - } - currentPosition += encodedLen; - remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen + result = + DleEncoder::encode(temporaryBuffer, 2, currentPosition, remainingLen, &encodedLen, false); + if (result != RETURN_OK) { + return result; + } + currentPosition += encodedLen; + remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen - //encoding the actual data - result = DleEncoder::encode(data, dataLen, currentPosition, remainingLen, - &encodedLen, false); - if (result != RETURN_OK) { - return result; - } - currentPosition += encodedLen; - remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen + if (remainingLen > 0) { + *currentPosition = DleEncoder::ETX_CHAR; + } + remainingLen -= 1; - uint16_t crc = CRC::crc16ccitt(&command, 1); - crc = CRC::crc16ccitt(&address, 1, crc); - //fortunately the length is still there - crc = CRC::crc16ccitt(temporaryBuffer, 2, crc); - crc = CRC::crc16ccitt(data, dataLen, crc); - - temporaryBuffer[0] = crc >> 8; - temporaryBuffer[1] = crc; - - result = DleEncoder::encode(temporaryBuffer, 2, currentPosition, - remainingLen, &encodedLen, false); - if (result != RETURN_OK) { - return result; - } - currentPosition += encodedLen; - remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen - - if (remainingLen > 0) { - *currentPosition = DleEncoder::ETX_CHAR; - } - remainingLen -= 1; - - encodedLen = sizeof(sendBuffer) - remainingLen; + encodedLen = sizeof(sendBuffer) - remainingLen; #ifdef LINUX - ssize_t writtenlen = ::write(serialPort, sendBuffer, encodedLen); - if (writtenlen < 0) { - //we could try to find out what happened... - return RETURN_FAILED; - } - if (writtenlen != encodedLen) { - //the OS failed us, we do not try to block until everything is written, as - //we can not block the whole system here - return RETURN_FAILED; - } - return RETURN_OK; + ssize_t writtenlen = ::write(serialPort, sendBuffer, encodedLen); + if (writtenlen < 0) { + // we could try to find out what happened... + return RETURN_FAILED; + } + if (writtenlen != encodedLen) { + // the OS failed us, we do not try to block until everything is written, as + // we can not block the whole system here + return RETURN_FAILED; + } + return RETURN_OK; #elif WIN32 - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; #endif } void ArduinoComIF::handleSerialPortRx() { #ifdef LINUX - uint32_t availableSpace = rxBuffer.availableWriteSpace(); + uint32_t availableSpace = rxBuffer.availableWriteSpace(); - uint8_t dataFromSerial[availableSpace]; + uint8_t dataFromSerial[availableSpace]; - ssize_t bytesRead = read(serialPort, dataFromSerial, - sizeof(dataFromSerial)); + ssize_t bytesRead = read(serialPort, dataFromSerial, sizeof(dataFromSerial)); - if (bytesRead < 0) { - return; - } + if (bytesRead < 0) { + return; + } - rxBuffer.writeData(dataFromSerial, bytesRead); + rxBuffer.writeData(dataFromSerial, bytesRead); - uint8_t dataReceivedSoFar[rxBuffer.getMaxSize()]; + uint8_t dataReceivedSoFar[rxBuffer.getMaxSize()]; - uint32_t dataLenReceivedSoFar = 0; + uint32_t dataLenReceivedSoFar = 0; - rxBuffer.readData(dataReceivedSoFar, sizeof(dataReceivedSoFar), true, - &dataLenReceivedSoFar); + rxBuffer.readData(dataReceivedSoFar, sizeof(dataReceivedSoFar), true, &dataLenReceivedSoFar); - //look for STX - size_t firstSTXinRawData = 0; - while ((firstSTXinRawData < dataLenReceivedSoFar) - && (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR)) { - firstSTXinRawData++; - } + // look for STX + size_t firstSTXinRawData = 0; + while ((firstSTXinRawData < dataLenReceivedSoFar) && + (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR)) { + firstSTXinRawData++; + } - if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR) { - //there is no STX in our data, throw it away... - rxBuffer.deleteData(dataLenReceivedSoFar); - return; - } + if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR) { + // there is no STX in our data, throw it away... + rxBuffer.deleteData(dataLenReceivedSoFar); + return; + } - uint8_t packet[MAX_PACKET_SIZE]; - size_t packetLen = 0; + uint8_t packet[MAX_PACKET_SIZE]; + size_t packetLen = 0; - size_t readSize = 0; + size_t readSize = 0; - ReturnValue_t result = DleEncoder::decode( - dataReceivedSoFar + firstSTXinRawData, - dataLenReceivedSoFar - firstSTXinRawData, &readSize, packet, - sizeof(packet), &packetLen); + ReturnValue_t result = DleEncoder::decode(dataReceivedSoFar + firstSTXinRawData, + dataLenReceivedSoFar - firstSTXinRawData, &readSize, + packet, sizeof(packet), &packetLen); - size_t toDelete = firstSTXinRawData; - if (result == HasReturnvaluesIF::RETURN_OK) { - handlePacket(packet, packetLen); + size_t toDelete = firstSTXinRawData; + if (result == HasReturnvaluesIF::RETURN_OK) { + handlePacket(packet, packetLen); - // after handling the packet, we can delete it from the raw stream, - // it has been copied to packet - toDelete += readSize; - } + // after handling the packet, we can delete it from the raw stream, + // it has been copied to packet + toDelete += readSize; + } - //remove Data which was processed - rxBuffer.deleteData(toDelete); + // remove Data which was processed + rxBuffer.deleteData(toDelete); #elif WIN32 #endif } -void ArduinoComIF::setBaudrate(uint32_t baudRate) { - this->baudRate = baudRate; -} +void ArduinoComIF::setBaudrate(uint32_t baudRate) { this->baudRate = baudRate; } void ArduinoComIF::handlePacket(uint8_t *packet, size_t packetLen) { - uint16_t crc = CRC::crc16ccitt(packet, packetLen); - if (crc != 0) { - //CRC error - return; - } + uint16_t crc = CRC::crc16ccitt(packet, packetLen); + if (crc != 0) { + // CRC error + return; + } - uint8_t command = packet[0]; - uint8_t address = packet[1]; + uint8_t command = packet[0]; + uint8_t address = packet[1]; - uint16_t size = (packet[2] << 8) + packet[3]; + uint16_t size = (packet[2] << 8) + packet[3]; - if (size != packetLen - 6) { - //Invalid Length - return; - } + if (size != packetLen - 6) { + // Invalid Length + return; + } - switch (command) { - case ArduinoCookie::SPI: { - //ArduinoCookie **itsComplicated; - auto findIter = spiMap.find(address); - if (findIter == spiMap.end()) { - //we do no know this address - return; - } - ArduinoCookie& cookie = findIter->second; - if (packetLen > cookie.maxReplySize + 6) { - packetLen = cookie.maxReplySize + 6; - } - std::memcpy(cookie.replyBuffer.data(), packet + 4, packetLen - 6); - cookie.receivedDataLen = packetLen - 6; - } - break; - default: - return; - } + switch (command) { + case ArduinoCookie::SPI: { + // ArduinoCookie **itsComplicated; + auto findIter = spiMap.find(address); + if (findIter == spiMap.end()) { + // we do no know this address + return; + } + ArduinoCookie &cookie = findIter->second; + if (packetLen > cookie.maxReplySize + 6) { + packetLen = cookie.maxReplySize + 6; + } + std::memcpy(cookie.replyBuffer.data(), packet + 4, packetLen - 6); + cookie.receivedDataLen = packetLen - 6; + } break; + default: + return; + } } diff --git a/bsp_hosted/comIF/ArduinoComIF.h b/bsp_hosted/comIF/ArduinoComIF.h index 84bd959d..8476b6b5 100644 --- a/bsp_hosted/comIF/ArduinoComIF.h +++ b/bsp_hosted/comIF/ArduinoComIF.h @@ -4,8 +4,8 @@ #include #include #include -#include #include +#include #include #include @@ -14,56 +14,53 @@ #include #endif -//Forward declaration, so users don't peek +// Forward declaration, so users don't peek class ArduinoCookie; -class ArduinoComIF: public SystemObject, - public DeviceCommunicationIF { -public: - static const uint8_t MAX_NUMBER_OF_SPI_DEVICES = 8; - static const uint8_t MAX_PACKET_SIZE = 64; +class ArduinoComIF : public SystemObject, public DeviceCommunicationIF { + public: + static const uint8_t MAX_NUMBER_OF_SPI_DEVICES = 8; + static const uint8_t MAX_PACKET_SIZE = 64; - static const uint8_t COMMAND_INVALID = -1; - static const uint8_t COMMAND_SPI = 1; + static const uint8_t COMMAND_INVALID = -1; + static const uint8_t COMMAND_SPI = 1; - ArduinoComIF(object_id_t setObjectId, bool promptComIF = false, - const char *serialDevice = nullptr); - void setBaudrate(uint32_t baudRate); + ArduinoComIF(object_id_t setObjectId, bool promptComIF = false, + const char *serialDevice = nullptr); + void setBaudrate(uint32_t baudRate); - virtual ~ArduinoComIF(); + virtual ~ArduinoComIF(); - /** DeviceCommunicationIF overrides */ - virtual ReturnValue_t initializeInterface(CookieIF * cookie) override; - virtual ReturnValue_t sendMessage(CookieIF *cookie, - const uint8_t * sendData, size_t sendLen) override; - virtual ReturnValue_t getSendSuccess(CookieIF *cookie) override; - virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, - size_t requestLen) override; - virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, - uint8_t **buffer, size_t *size) override; + /** DeviceCommunicationIF overrides */ + virtual ReturnValue_t initializeInterface(CookieIF *cookie) override; + virtual ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t *sendData, + size_t sendLen) override; + virtual ReturnValue_t getSendSuccess(CookieIF *cookie) override; + virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) override; + virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, + size_t *size) override; -private: + private: #ifdef LINUX #elif WIN32 - HANDLE hCom = INVALID_HANDLE_VALUE; + HANDLE hCom = INVALID_HANDLE_VALUE; #endif - // remembering if the initialization in the ctor worked - // if not, all calls are disabled - bool initialized = false; - int serialPort = 0; - // Default baud rate is 9600 for now. - uint32_t baudRate = 9600; + // remembering if the initialization in the ctor worked + // if not, all calls are disabled + bool initialized = false; + int serialPort = 0; + // Default baud rate is 9600 for now. + uint32_t baudRate = 9600; - //used to know where to put the data if a reply is received - std::map spiMap; + // used to know where to put the data if a reply is received + std::map spiMap; - SimpleRingBuffer rxBuffer; + SimpleRingBuffer rxBuffer; - ReturnValue_t sendMessage(uint8_t command, uint8_t address, - const uint8_t *data, size_t dataLen); - void handleSerialPortRx(); + ReturnValue_t sendMessage(uint8_t command, uint8_t address, const uint8_t *data, size_t dataLen); + void handleSerialPortRx(); - void handlePacket(uint8_t *packet, size_t packetLen); + void handlePacket(uint8_t *packet, size_t packetLen); }; #endif /* MISSION_ARDUINOCOMMINTERFACE_H_ */ diff --git a/bsp_hosted/comIF/ArduinoCookie.cpp b/bsp_hosted/comIF/ArduinoCookie.cpp index bc698720..89cb1568 100644 --- a/bsp_hosted/comIF/ArduinoCookie.cpp +++ b/bsp_hosted/comIF/ArduinoCookie.cpp @@ -1,8 +1,8 @@ #include -ArduinoCookie::ArduinoCookie(Protocol_t protocol, uint8_t address, - const size_t maxReplySize) : - protocol(protocol), command(protocol), address(address), - maxReplySize(maxReplySize), replyBuffer(maxReplySize) { -} - +ArduinoCookie::ArduinoCookie(Protocol_t protocol, uint8_t address, const size_t maxReplySize) + : protocol(protocol), + command(protocol), + address(address), + maxReplySize(maxReplySize), + replyBuffer(maxReplySize) {} diff --git a/bsp_hosted/comIF/ArduinoCookie.h b/bsp_hosted/comIF/ArduinoCookie.h index a5f91f64..04d4bd83 100644 --- a/bsp_hosted/comIF/ArduinoCookie.h +++ b/bsp_hosted/comIF/ArduinoCookie.h @@ -2,26 +2,21 @@ #define MISSION_ARDUINO_ARDUINOCOOKIE_H_ #include + #include -class ArduinoCookie: public CookieIF { -public: - enum Protocol_t: uint8_t { - INVALID, - SPI, - I2C - }; +class ArduinoCookie : public CookieIF { + public: + enum Protocol_t : uint8_t { INVALID, SPI, I2C }; - ArduinoCookie(Protocol_t protocol, uint8_t address, - const size_t maxReplySize); - - Protocol_t protocol; - uint8_t command; - uint8_t address; - std::vector replyBuffer; - size_t receivedDataLen = 0; - size_t maxReplySize; + ArduinoCookie(Protocol_t protocol, uint8_t address, const size_t maxReplySize); + Protocol_t protocol; + uint8_t command; + uint8_t address; + std::vector replyBuffer; + size_t receivedDataLen = 0; + size_t maxReplySize; }; #endif /* MISSION_ARDUINO_ARDUINOCOOKIE_H_ */ diff --git a/bsp_hosted/fsfwconfig/CMakeLists.txt b/bsp_hosted/fsfwconfig/CMakeLists.txt index fc961da8..4a483eb7 100644 --- a/bsp_hosted/fsfwconfig/CMakeLists.txt +++ b/bsp_hosted/fsfwconfig/CMakeLists.txt @@ -1,21 +1,27 @@ -target_sources(${TARGET_NAME} PRIVATE +target_sources(${OBSW_NAME} PRIVATE ipc/MissionMessageTypes.cpp ) -target_include_directories(${TARGET_NAME} PUBLIC +target_include_directories(${OBSW_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) # If a special translation file for object IDs exists, compile it. if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp") - target_sources(${TARGET_NAME} PRIVATE + target_sources(${OBSW_NAME} PRIVATE + objects/translateObjects.cpp + ) + target_sources(${UNITTEST_NAME} PRIVATE objects/translateObjects.cpp ) endif() # If a special translation file for events exists, compile it. if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp") - target_sources(${TARGET_NAME} PRIVATE + target_sources(${OBSW_NAME} PRIVATE + events/translateEvents.cpp + ) + target_sources(${UNITTEST_NAME} PRIVATE events/translateEvents.cpp ) endif() diff --git a/bsp_hosted/fsfwconfig/devices/gpioIds.h b/bsp_hosted/fsfwconfig/devices/gpioIds.h deleted file mode 100644 index a4b4ac81..00000000 --- a/bsp_hosted/fsfwconfig/devices/gpioIds.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef FSFWCONFIG_DEVICES_GPIOIDS_H_ -#define FSFWCONFIG_DEVICES_GPIOIDS_H_ - -namespace gpioIds { - enum gpioId_t { - HEATER_0, - HEATER_1, - HEATER_2, - HEATER_3, - HEATER_4, - HEATER_5, - HEATER_6, - HEATER_7, - DEPLSA1, - DEPLSA2, - - MGM_0_LIS3_CS, - MGM_1_RM3100_CS, - GYRO_0_ADIS_CS, - GYRO_1_L3G_CS, - GYRO_2_L3G_CS, - MGM_2_LIS3_CS, - MGM_3_RM3100_CS, - - TEST_ID_0, - TEST_ID_1, - - RTD_IC_3, - RTD_IC_4, - RTD_IC_5, - RTD_IC_6, - RTD_IC_7, - RTD_IC_8, - RTD_IC_9, - RTD_IC_10, - RTD_IC_11, - RTD_IC_12, - RTD_IC_13, - RTD_IC_14, - RTD_IC_15, - RTD_IC_16, - RTD_IC_17, - RTD_IC_18, - - SPI_MUX_BIT_1, - SPI_MUX_BIT_2, - SPI_MUX_BIT_3, - SPI_MUX_BIT_4, - SPI_MUX_BIT_5, - SPI_MUX_BIT_6 - }; -} - - - - -#endif /* FSFWCONFIG_DEVICES_GPIOIDS_H_ */ diff --git a/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h b/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h deleted file mode 100644 index c216c828..00000000 --- a/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ -#define FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ - -#include - -namespace pcduSwitches { - /* Switches are uint8_t datatype and go from 0 to 255 */ - enum SwitcherList { - Q7S, - PAYLOAD_PCDU_CH1, - RW, - TCS_BOARD_8V_HEATER_IN, - SUS_REDUNDANT, - DEPLOYMENT_MECHANISM, - PAYLOAD_PCDU_CH6, - ACS_BOARD_SIDE_B, - PAYLOAD_CAMERA, - TCS_BOARD_3V3, - SYRLINKS, - STAR_TRACKER, - MGT, - SUS_NOMINAL, - SOLAR_CELL_EXP, - PLOC, - ACS_BOARD_SIDE_A, - NUMBER_OF_SWITCHES - }; - - static const uint8_t ON = 1; - static const uint8_t OFF = 0; - - /* Output states after reboot of the PDUs */ - static const uint8_t INIT_STATE_Q7S = ON; - static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; - static const uint8_t INIT_STATE_RW = OFF; -#if BOARD_TE0720 == 1 - /* Because the TE0720 is not connected to the PCDU, this switch is always on */ - static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; -#else - static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; -#endif - static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; - static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; - static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; - static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; - static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; - static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; - static const uint8_t INIT_STATE_SYRLINKS = OFF; - static const uint8_t INIT_STATE_STAR_TRACKER = OFF; - static const uint8_t INIT_STATE_MGT = OFF; - static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; - static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; - static const uint8_t INIT_STATE_PLOC = OFF; - static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; -} - - -#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */ diff --git a/bsp_hosted/fsfwconfig/events/subsystemIdRanges.h b/bsp_hosted/fsfwconfig/events/subsystemIdRanges.h index 7335a804..9dc50c50 100644 --- a/bsp_hosted/fsfwconfig/events/subsystemIdRanges.h +++ b/bsp_hosted/fsfwconfig/events/subsystemIdRanges.h @@ -2,6 +2,7 @@ #define CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_ #include + #include /** @@ -9,9 +10,7 @@ * Numbers 0-80 are reserved for FSFW Subsystem IDs (framework/events/) */ namespace SUBSYSTEM_ID { -enum: uint8_t { - SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_END -}; +enum : uint8_t { SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_END }; } #endif /* CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_ */ diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index 7b9ce4b5..fb9e1bf4 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.cpp +++ b/bsp_hosted/fsfwconfig/events/translateEvents.cpp @@ -89,176 +89,176 @@ const char *ACK_FAILURE_STRING = "ACK_FAILURE"; const char *EXE_FAILURE_STRING = "EXE_FAILURE"; const char *CRC_FAILURE_EVENT_STRING = "CRC_FAILURE_EVENT"; -const char * translateEvents(Event event) { - switch( (event & 0xffff) ) { - case(2200): - return STORE_SEND_WRITE_FAILED_STRING; - case(2201): - return STORE_WRITE_FAILED_STRING; - case(2202): - return STORE_SEND_READ_FAILED_STRING; - case(2203): - return STORE_READ_FAILED_STRING; - case(2204): - return UNEXPECTED_MSG_STRING; - case(2205): - return STORING_FAILED_STRING; - case(2206): - return TM_DUMP_FAILED_STRING; - case(2207): - return STORE_INIT_FAILED_STRING; - case(2208): - return STORE_INIT_EMPTY_STRING; - case(2209): - return STORE_CONTENT_CORRUPTED_STRING; - case(2210): - return STORE_INITIALIZE_STRING; - case(2211): - return INIT_DONE_STRING; - case(2212): - return DUMP_FINISHED_STRING; - case(2213): - return DELETION_FINISHED_STRING; - case(2214): - return DELETION_FAILED_STRING; - case(2215): - return AUTO_CATALOGS_SENDING_FAILED_STRING; - case(2600): - return GET_DATA_FAILED_STRING; - case(2601): - return STORE_DATA_FAILED_STRING; - case(2800): - return DEVICE_BUILDING_COMMAND_FAILED_STRING; - case(2801): - return DEVICE_SENDING_COMMAND_FAILED_STRING; - case(2802): - return DEVICE_REQUESTING_REPLY_FAILED_STRING; - case(2803): - return DEVICE_READING_REPLY_FAILED_STRING; - case(2804): - return DEVICE_INTERPRETING_REPLY_FAILED_STRING; - case(2805): - return DEVICE_MISSED_REPLY_STRING; - case(2806): - return DEVICE_UNKNOWN_REPLY_STRING; - case(2807): - return DEVICE_UNREQUESTED_REPLY_STRING; - case(2808): - return INVALID_DEVICE_COMMAND_STRING; - case(2809): - return MONITORING_LIMIT_EXCEEDED_STRING; - case(2810): - return MONITORING_AMBIGUOUS_STRING; - case(4201): - return FUSE_CURRENT_HIGH_STRING; - case(4202): - return FUSE_WENT_OFF_STRING; - case(4204): - return POWER_ABOVE_HIGH_LIMIT_STRING; - case(4205): - return POWER_BELOW_LOW_LIMIT_STRING; - case(4300): - return SWITCH_WENT_OFF_STRING; - case(5000): - return HEATER_ON_STRING; - case(5001): - return HEATER_OFF_STRING; - case(5002): - return HEATER_TIMEOUT_STRING; - case(5003): - return HEATER_STAYED_ON_STRING; - case(5004): - return HEATER_STAYED_OFF_STRING; - case(5200): - return TEMP_SENSOR_HIGH_STRING; - case(5201): - return TEMP_SENSOR_LOW_STRING; - case(5202): - return TEMP_SENSOR_GRADIENT_STRING; - case(5901): - return COMPONENT_TEMP_LOW_STRING; - case(5902): - return COMPONENT_TEMP_HIGH_STRING; - case(5903): - return COMPONENT_TEMP_OOL_LOW_STRING; - case(5904): - return COMPONENT_TEMP_OOL_HIGH_STRING; - case(5905): - return TEMP_NOT_IN_OP_RANGE_STRING; - case(7101): - return FDIR_CHANGED_STATE_STRING; - case(7102): - return FDIR_STARTS_RECOVERY_STRING; - case(7103): - return FDIR_TURNS_OFF_DEVICE_STRING; - case(7201): - return MONITOR_CHANGED_STATE_STRING; - case(7202): - return VALUE_BELOW_LOW_LIMIT_STRING; - case(7203): - return VALUE_ABOVE_HIGH_LIMIT_STRING; - case(7204): - return VALUE_OUT_OF_RANGE_STRING; - case(7301): - return SWITCHING_TM_FAILED_STRING; - case(7400): - return CHANGING_MODE_STRING; - case(7401): - return MODE_INFO_STRING; - case(7402): - return FALLBACK_FAILED_STRING; - case(7403): - return MODE_TRANSITION_FAILED_STRING; - case(7404): - return CANT_KEEP_MODE_STRING; - case(7405): - return OBJECT_IN_INVALID_MODE_STRING; - case(7406): - return FORCING_MODE_STRING; - case(7407): - return MODE_CMD_REJECTED_STRING; - case(7506): - return HEALTH_INFO_STRING; - case(7507): - return CHILD_CHANGED_HEALTH_STRING; - case(7508): - return CHILD_PROBLEMS_STRING; - case(7509): - return OVERWRITING_HEALTH_STRING; - case(7510): - return TRYING_RECOVERY_STRING; - case(7511): - return RECOVERY_STEP_STRING; - case(7512): - return RECOVERY_DONE_STRING; - case(7900): - return RF_AVAILABLE_STRING; - case(7901): - return RF_LOST_STRING; - case(7902): - return BIT_LOCK_STRING; - case(7903): - return BIT_LOCK_LOST_STRING; - case(7905): - return FRAME_PROCESSING_FAILED_STRING; - case(8900): - return CLOCK_SET_STRING; - case(8901): - return CLOCK_SET_FAILURE_STRING; - case(9700): - return TEST_STRING; - case(10600): - return CHANGE_OF_SETUP_PARAMETER_STRING; - case(11101): - return MEMORY_READ_RPT_CRC_FAILURE_STRING; - case(11102): - return ACK_FAILURE_STRING; - case(11103): - return EXE_FAILURE_STRING; - case(11104): - return CRC_FAILURE_EVENT_STRING; - default: - return "UNKNOWN_EVENT"; - } - return 0; +const char *translateEvents(Event event) { + switch ((event & 0xffff)) { + case (2200): + return STORE_SEND_WRITE_FAILED_STRING; + case (2201): + return STORE_WRITE_FAILED_STRING; + case (2202): + return STORE_SEND_READ_FAILED_STRING; + case (2203): + return STORE_READ_FAILED_STRING; + case (2204): + return UNEXPECTED_MSG_STRING; + case (2205): + return STORING_FAILED_STRING; + case (2206): + return TM_DUMP_FAILED_STRING; + case (2207): + return STORE_INIT_FAILED_STRING; + case (2208): + return STORE_INIT_EMPTY_STRING; + case (2209): + return STORE_CONTENT_CORRUPTED_STRING; + case (2210): + return STORE_INITIALIZE_STRING; + case (2211): + return INIT_DONE_STRING; + case (2212): + return DUMP_FINISHED_STRING; + case (2213): + return DELETION_FINISHED_STRING; + case (2214): + return DELETION_FAILED_STRING; + case (2215): + return AUTO_CATALOGS_SENDING_FAILED_STRING; + case (2600): + return GET_DATA_FAILED_STRING; + case (2601): + return STORE_DATA_FAILED_STRING; + case (2800): + return DEVICE_BUILDING_COMMAND_FAILED_STRING; + case (2801): + return DEVICE_SENDING_COMMAND_FAILED_STRING; + case (2802): + return DEVICE_REQUESTING_REPLY_FAILED_STRING; + case (2803): + return DEVICE_READING_REPLY_FAILED_STRING; + case (2804): + return DEVICE_INTERPRETING_REPLY_FAILED_STRING; + case (2805): + return DEVICE_MISSED_REPLY_STRING; + case (2806): + return DEVICE_UNKNOWN_REPLY_STRING; + case (2807): + return DEVICE_UNREQUESTED_REPLY_STRING; + case (2808): + return INVALID_DEVICE_COMMAND_STRING; + case (2809): + return MONITORING_LIMIT_EXCEEDED_STRING; + case (2810): + return MONITORING_AMBIGUOUS_STRING; + case (4201): + return FUSE_CURRENT_HIGH_STRING; + case (4202): + return FUSE_WENT_OFF_STRING; + case (4204): + return POWER_ABOVE_HIGH_LIMIT_STRING; + case (4205): + return POWER_BELOW_LOW_LIMIT_STRING; + case (4300): + return SWITCH_WENT_OFF_STRING; + case (5000): + return HEATER_ON_STRING; + case (5001): + return HEATER_OFF_STRING; + case (5002): + return HEATER_TIMEOUT_STRING; + case (5003): + return HEATER_STAYED_ON_STRING; + case (5004): + return HEATER_STAYED_OFF_STRING; + case (5200): + return TEMP_SENSOR_HIGH_STRING; + case (5201): + return TEMP_SENSOR_LOW_STRING; + case (5202): + return TEMP_SENSOR_GRADIENT_STRING; + case (5901): + return COMPONENT_TEMP_LOW_STRING; + case (5902): + return COMPONENT_TEMP_HIGH_STRING; + case (5903): + return COMPONENT_TEMP_OOL_LOW_STRING; + case (5904): + return COMPONENT_TEMP_OOL_HIGH_STRING; + case (5905): + return TEMP_NOT_IN_OP_RANGE_STRING; + case (7101): + return FDIR_CHANGED_STATE_STRING; + case (7102): + return FDIR_STARTS_RECOVERY_STRING; + case (7103): + return FDIR_TURNS_OFF_DEVICE_STRING; + case (7201): + return MONITOR_CHANGED_STATE_STRING; + case (7202): + return VALUE_BELOW_LOW_LIMIT_STRING; + case (7203): + return VALUE_ABOVE_HIGH_LIMIT_STRING; + case (7204): + return VALUE_OUT_OF_RANGE_STRING; + case (7301): + return SWITCHING_TM_FAILED_STRING; + case (7400): + return CHANGING_MODE_STRING; + case (7401): + return MODE_INFO_STRING; + case (7402): + return FALLBACK_FAILED_STRING; + case (7403): + return MODE_TRANSITION_FAILED_STRING; + case (7404): + return CANT_KEEP_MODE_STRING; + case (7405): + return OBJECT_IN_INVALID_MODE_STRING; + case (7406): + return FORCING_MODE_STRING; + case (7407): + return MODE_CMD_REJECTED_STRING; + case (7506): + return HEALTH_INFO_STRING; + case (7507): + return CHILD_CHANGED_HEALTH_STRING; + case (7508): + return CHILD_PROBLEMS_STRING; + case (7509): + return OVERWRITING_HEALTH_STRING; + case (7510): + return TRYING_RECOVERY_STRING; + case (7511): + return RECOVERY_STEP_STRING; + case (7512): + return RECOVERY_DONE_STRING; + case (7900): + return RF_AVAILABLE_STRING; + case (7901): + return RF_LOST_STRING; + case (7902): + return BIT_LOCK_STRING; + case (7903): + return BIT_LOCK_LOST_STRING; + case (7905): + return FRAME_PROCESSING_FAILED_STRING; + case (8900): + return CLOCK_SET_STRING; + case (8901): + return CLOCK_SET_FAILURE_STRING; + case (9700): + return TEST_STRING; + case (10600): + return CHANGE_OF_SETUP_PARAMETER_STRING; + case (11101): + return MEMORY_READ_RPT_CRC_FAILURE_STRING; + case (11102): + return ACK_FAILURE_STRING; + case (11103): + return EXE_FAILURE_STRING; + case (11104): + return CRC_FAILURE_EVENT_STRING; + default: + return "UNKNOWN_EVENT"; + } + return 0; } diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.h b/bsp_hosted/fsfwconfig/events/translateEvents.h index 9034dcf2..a42d9b5a 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.h +++ b/bsp_hosted/fsfwconfig/events/translateEvents.h @@ -3,6 +3,6 @@ #include -const char * translateEvents(Event event); +const char* translateEvents(Event event); #endif /* FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ */ diff --git a/bsp_hosted/fsfwconfig/ipc/MissionMessageTypes.cpp b/bsp_hosted/fsfwconfig/ipc/MissionMessageTypes.cpp index 36ef1b73..fa1c4877 100644 --- a/bsp_hosted/fsfwconfig/ipc/MissionMessageTypes.cpp +++ b/bsp_hosted/fsfwconfig/ipc/MissionMessageTypes.cpp @@ -1,11 +1,10 @@ #include "MissionMessageTypes.h" + #include void messagetypes::clearMissionMessage(CommandMessage* message) { - switch(message->getMessageType()) { - default: - break; - } + switch (message->getMessageType()) { + default: + break; + } } - - diff --git a/bsp_hosted/fsfwconfig/ipc/MissionMessageTypes.h b/bsp_hosted/fsfwconfig/ipc/MissionMessageTypes.h index 7e3c448f..1d93ba21 100644 --- a/bsp_hosted/fsfwconfig/ipc/MissionMessageTypes.h +++ b/bsp_hosted/fsfwconfig/ipc/MissionMessageTypes.h @@ -13,10 +13,10 @@ class CommandMessage; */ namespace messagetypes { enum MESSAGE_TYPE { - MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT, + MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT, }; void clearMissionMessage(CommandMessage* message); -} +} // namespace messagetypes #endif /* CONFIG_IPC_MISSIONMESSAGETYPES_H_ */ diff --git a/bsp_hosted/fsfwconfig/objects/systemObjectList.h b/bsp_hosted/fsfwconfig/objects/systemObjectList.h index 21a5f939..91bd2bed 100644 --- a/bsp_hosted/fsfwconfig/objects/systemObjectList.h +++ b/bsp_hosted/fsfwconfig/objects/systemObjectList.h @@ -1,31 +1,32 @@ #ifndef HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ #define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ -#include #include +#include + // The objects will be instantiated in the ID order namespace objects { - enum sourceObjects: uint32_t { +enum sourceObjects : uint32_t { - PUS_SERVICE_3 = 0x51000300, - PUS_SERVICE_5 = 0x51000400, - PUS_SERVICE_6 = 0x51000500, - PUS_SERVICE_8 = 0x51000800, - PUS_SERVICE_23 = 0x51002300, - PUS_SERVICE_201 = 0x51020100, + PUS_SERVICE_3 = 0x51000300, + PUS_SERVICE_5 = 0x51000400, + PUS_SERVICE_6 = 0x51000500, + PUS_SERVICE_8 = 0x51000800, + PUS_SERVICE_23 = 0x51002300, + PUS_SERVICE_201 = 0x51020100, - TM_FUNNEL = 0x52000002, + TM_FUNNEL = 0x52000002, - /* Test Task */ + /* Test Task */ - TEST_TASK = 0x42694269, - DUMMY_INTERFACE = 0xCAFECAFE, - DUMMY_HANDLER = 0x4400AFFE, + TEST_TASK = 0x42694269, + DUMMY_INTERFACE = 0xCAFECAFE, + DUMMY_HANDLER = 0x4400AFFE, - /* 0x49 ('I') for Communication Interfaces **/ - ARDUINO_COM_IF = 0x49000001 - }; + /* 0x49 ('I') for Communication Interfaces **/ + ARDUINO_COM_IF = 0x49000001 +}; } #endif /* BSP_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */ diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index 9aac2b47..f29e4d65 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -1,4 +1,4 @@ -/** +/** * @brief Auto-generated object translation file. * @details * Contains 31 translations. @@ -38,72 +38,72 @@ const char *FSFW_OBJECTS_END_STRING = "FSFW_OBJECTS_END"; const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE"; const char *NO_OBJECT_STRING = "NO_OBJECT"; -const char* translateObject(object_id_t object) { - switch( (object & 0xFFFFFFFF) ) { - case 0x42694269: - return TEST_TASK_STRING; - case 0x4400AFFE: - return DUMMY_HANDLER_STRING; - case 0x49000001: - return ARDUINO_COM_IF_STRING; - case 0x51000300: - return PUS_SERVICE_3_STRING; - case 0x51000400: - return PUS_SERVICE_5_STRING; - case 0x51000500: - return PUS_SERVICE_6_STRING; - case 0x51000800: - return PUS_SERVICE_8_STRING; - case 0x51002300: - return PUS_SERVICE_23_STRING; - case 0x51020100: - return PUS_SERVICE_201_STRING; - case 0x52000002: - return TM_FUNNEL_STRING; - case 0x53000000: - return FSFW_OBJECTS_START_STRING; - case 0x53000001: - return PUS_SERVICE_1_VERIFICATION_STRING; - case 0x53000002: - return PUS_SERVICE_2_DEVICE_ACCESS_STRING; - case 0x53000003: - return PUS_SERVICE_3_HOUSEKEEPING_STRING; - case 0x53000005: - return PUS_SERVICE_5_EVENT_REPORTING_STRING; - case 0x53000008: - return PUS_SERVICE_8_FUNCTION_MGMT_STRING; - case 0x53000009: - return PUS_SERVICE_9_TIME_MGMT_STRING; - case 0x53000017: - return PUS_SERVICE_17_TEST_STRING; - case 0x53000020: - return PUS_SERVICE_20_PARAMETERS_STRING; - case 0x53000200: - return PUS_SERVICE_200_MODE_MGMT_STRING; - case 0x53010000: - return HEALTH_TABLE_STRING; - case 0x53010100: - return MODE_STORE_STRING; - case 0x53030000: - return EVENT_MANAGER_STRING; - case 0x53040000: - return INTERNAL_ERROR_REPORTER_STRING; - case 0x534f0100: - return TC_STORE_STRING; - case 0x534f0200: - return TM_STORE_STRING; - case 0x534f0300: - return IPC_STORE_STRING; - case 0x53500010: - return TIME_STAMPER_STRING; - case 0x53ffffff: - return FSFW_OBJECTS_END_STRING; - case 0xCAFECAFE: - return DUMMY_INTERFACE_STRING; - case 0xFFFFFFFF: - return NO_OBJECT_STRING; - default: - return "UNKNOWN_OBJECT"; - } - return 0; +const char *translateObject(object_id_t object) { + switch ((object & 0xFFFFFFFF)) { + case 0x42694269: + return TEST_TASK_STRING; + case 0x4400AFFE: + return DUMMY_HANDLER_STRING; + case 0x49000001: + return ARDUINO_COM_IF_STRING; + case 0x51000300: + return PUS_SERVICE_3_STRING; + case 0x51000400: + return PUS_SERVICE_5_STRING; + case 0x51000500: + return PUS_SERVICE_6_STRING; + case 0x51000800: + return PUS_SERVICE_8_STRING; + case 0x51002300: + return PUS_SERVICE_23_STRING; + case 0x51020100: + return PUS_SERVICE_201_STRING; + case 0x52000002: + return TM_FUNNEL_STRING; + case 0x53000000: + return FSFW_OBJECTS_START_STRING; + case 0x53000001: + return PUS_SERVICE_1_VERIFICATION_STRING; + case 0x53000002: + return PUS_SERVICE_2_DEVICE_ACCESS_STRING; + case 0x53000003: + return PUS_SERVICE_3_HOUSEKEEPING_STRING; + case 0x53000005: + return PUS_SERVICE_5_EVENT_REPORTING_STRING; + case 0x53000008: + return PUS_SERVICE_8_FUNCTION_MGMT_STRING; + case 0x53000009: + return PUS_SERVICE_9_TIME_MGMT_STRING; + case 0x53000017: + return PUS_SERVICE_17_TEST_STRING; + case 0x53000020: + return PUS_SERVICE_20_PARAMETERS_STRING; + case 0x53000200: + return PUS_SERVICE_200_MODE_MGMT_STRING; + case 0x53010000: + return HEALTH_TABLE_STRING; + case 0x53010100: + return MODE_STORE_STRING; + case 0x53030000: + return EVENT_MANAGER_STRING; + case 0x53040000: + return INTERNAL_ERROR_REPORTER_STRING; + case 0x534f0100: + return TC_STORE_STRING; + case 0x534f0200: + return TM_STORE_STRING; + case 0x534f0300: + return IPC_STORE_STRING; + case 0x53500010: + return TIME_STAMPER_STRING; + case 0x53ffffff: + return FSFW_OBJECTS_END_STRING; + case 0xCAFECAFE: + return DUMMY_INTERFACE_STRING; + case 0xFFFFFFFF: + return NO_OBJECT_STRING; + default: + return "UNKNOWN_OBJECT"; + } + return 0; } diff --git a/bsp_hosted/fsfwconfig/returnvalues/classIds.h b/bsp_hosted/fsfwconfig/returnvalues/classIds.h index cc159fec..b50e8ac0 100644 --- a/bsp_hosted/fsfwconfig/returnvalues/classIds.h +++ b/bsp_hosted/fsfwconfig/returnvalues/classIds.h @@ -1,9 +1,10 @@ #ifndef CONFIG_RETURNVALUES_CLASSIDS_H_ #define CONFIG_RETURNVALUES_CLASSIDS_H_ -#include "commonClassIds.h" #include +#include "commonClassIds.h" + /** * Source IDs starts at 73 for now * Framework IDs for ReturnValues run from 0 to 56 @@ -11,9 +12,8 @@ */ namespace CLASS_ID { enum { - CLASS_ID_START = COMMON_CLASS_ID_END, + CLASS_ID_START = COMMON_CLASS_ID_END, }; } - #endif /* CONFIG_RETURNVALUES_CLASSIDS_H_ */ diff --git a/bsp_hosted/fsfwconfig/tmtc/apid.h b/bsp_hosted/fsfwconfig/tmtc/apid.h index ee2fc7c4..9d5c9ed5 100644 --- a/bsp_hosted/fsfwconfig/tmtc/apid.h +++ b/bsp_hosted/fsfwconfig/tmtc/apid.h @@ -12,8 +12,7 @@ * APID is a 11 bit number */ namespace apid { - static const uint16_t EIVE_OBSW = 0x65; +static const uint16_t EIVE_OBSW = 0x65; } - #endif /* FSFWCONFIG_TMTC_APID_H_ */ diff --git a/bsp_hosted/fsfwconfig/tmtc/pusIds.h b/bsp_hosted/fsfwconfig/tmtc/pusIds.h index a2dd7575..37503786 100644 --- a/bsp_hosted/fsfwconfig/tmtc/pusIds.h +++ b/bsp_hosted/fsfwconfig/tmtc/pusIds.h @@ -2,21 +2,21 @@ #define CONFIG_TMTC_PUSIDS_HPP_ namespace pus { -enum Ids{ - PUS_SERVICE_1 = 1, - PUS_SERVICE_2 = 2, - PUS_SERVICE_3 = 3, - PUS_SERVICE_3_PSB = 3, - PUS_SERVICE_5 = 5, - PUS_SERVICE_6 = 6, - PUS_SERVICE_8 = 8, - PUS_SERVICE_9 = 9, - PUS_SERVICE_17 = 17, - PUS_SERVICE_19 = 19, - PUS_SERVICE_20 = 20, - PUS_SERVICE_23 = 23, - PUS_SERVICE_200 = 200, - PUS_SERVICE_201 = 201, +enum Ids { + PUS_SERVICE_1 = 1, + PUS_SERVICE_2 = 2, + PUS_SERVICE_3 = 3, + PUS_SERVICE_3_PSB = 3, + PUS_SERVICE_5 = 5, + PUS_SERVICE_6 = 6, + PUS_SERVICE_8 = 8, + PUS_SERVICE_9 = 9, + PUS_SERVICE_17 = 17, + PUS_SERVICE_19 = 19, + PUS_SERVICE_20 = 20, + PUS_SERVICE_23 = 23, + PUS_SERVICE_200 = 200, + PUS_SERVICE_201 = 201, }; }; diff --git a/bsp_hosted/main.cpp b/bsp_hosted/main.cpp index 153cc447..b7ebc422 100644 --- a/bsp_hosted/main.cpp +++ b/bsp_hosted/main.cpp @@ -1,10 +1,9 @@ +#include + #include "InitMission.h" #include "OBSWVersion.h" - #include "fsfw/FSFWVersion.h" #include "fsfw/tasks/TaskFactory.h" - -#include #ifdef WIN32 static const char* COMPILE_PRINTOUT = "Windows"; #elif LINUX @@ -17,21 +16,18 @@ static const char* COMPILE_PRINTOUT = "unknown OS"; * Linux and Windows. * @return */ -int main(void) -{ - std::cout << "-- EIVE OBSW --" << std::endl; - std::cout << "-- Compiled for " << COMPILE_PRINTOUT << " --" << std::endl; - std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << - "." << SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << "." << - FSFW_REVISION << "--" << std::endl; - std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; +int main(void) { + std::cout << "-- EIVE OBSW --" << std::endl; + std::cout << "-- Compiled for " << COMPILE_PRINTOUT << " --" << std::endl; + std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << "." + << SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << "." + << FSFW_REVISION << "--" << std::endl; + std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; - initmission::initMission(); + initmission::initMission(); - for(;;) { - // suspend main thread by sleeping it. - TaskFactory::delayTask(5000); - } + for (;;) { + // suspend main thread by sleeping it. + TaskFactory::delayTask(5000); + } } - - diff --git a/bsp_linux_board/CMakeLists.txt b/bsp_linux_board/CMakeLists.txt index 5963d48c..0272f476 100644 --- a/bsp_linux_board/CMakeLists.txt +++ b/bsp_linux_board/CMakeLists.txt @@ -1,4 +1,4 @@ -target_sources(${TARGET_NAME} PUBLIC +target_sources(${OBSW_NAME} PUBLIC InitMission.cpp main.cpp ObjectFactory.cpp diff --git a/bsp_linux_board/InitMission.cpp b/bsp_linux_board/InitMission.cpp index d265fded..6dfe3af1 100644 --- a/bsp_linux_board/InitMission.cpp +++ b/bsp_linux_board/InitMission.cpp @@ -1,247 +1,245 @@ #include "InitMission.h" -#include "ObjectFactory.h" -#include "objects/systemObjectList.h" -#include "OBSWConfig.h" -#include "pollingsequence/pollingSequenceFactory.h" - -#include +#include #include #include #include -#include #include #include #include +#include #include +#include "OBSWConfig.h" +#include "ObjectFactory.h" +#include "objects/systemObjectList.h" +#include "pollingsequence/pollingSequenceFactory.h" + ServiceInterfaceStream sif::debug("DEBUG"); ServiceInterfaceStream sif::info("INFO"); ServiceInterfaceStream sif::warning("WARNING"); ServiceInterfaceStream sif::error("ERROR"); -ObjectManagerIF *objectManager = nullptr; +ObjectManagerIF* objectManager = nullptr; void initmission::initMission() { - sif::info << "Building global objects.." << std::endl; - /* Instantiate global object manager and also create all objects */ - ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr); - sif::info << "Initializing all objects.." << std::endl; - ObjectManager::instance()->initialize(); + sif::info << "Building global objects.." << std::endl; + /* Instantiate global object manager and also create all objects */ + ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr); + sif::info << "Initializing all objects.." << std::endl; + ObjectManager::instance()->initialize(); - /* This function creates and starts all tasks */ - initTasks(); + /* This function creates and starts all tasks */ + initTasks(); } void initmission::initTasks() { - TaskFactory* factory = TaskFactory::instance(); - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - if(factory == nullptr) { - /* Should never happen ! */ - return; - } + TaskFactory* factory = TaskFactory::instance(); + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if (factory == nullptr) { + /* Should never happen ! */ + return; + } #if OBSW_PRINT_MISSED_DEADLINES == 1 - void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline; + void (*missedDeadlineFunc)(void) = TaskFactory::printMissedDeadline; #else - void (*missedDeadlineFunc) (void) = nullptr; + void (*missedDeadlineFunc)(void) = nullptr; #endif + /* TMTC Distribution */ + PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + result = tmTcDistributor->addComponent(objects::TM_FUNNEL); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } - /* TMTC Distribution */ - PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( - "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - result = tmTcDistributor->addComponent(objects::TM_FUNNEL); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Object add component failed" << std::endl; - } + /* UDP bridge */ + PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask( + "TMTC_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component TMTC Bridge failed" << std::endl; + } + PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( + "TMTC_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component TMTC Polling failed" << std::endl; + } - /* UDP bridge */ - PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( - "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = udpBridgeTask->addComponent(objects::TMTC_BRIDGE); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Add component UDP Unix Bridge failed" << std::endl; - } - PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( - "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = udpPollingTask->addComponent(objects::TMTC_POLLING_TASK); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Add component UDP Polling failed" << std::endl; - } + /* PUS Services */ + std::vector pusTasks; + createPusTasks(*factory, missedDeadlineFunc, pusTasks); - /* PUS Services */ - std::vector pusTasks; - createPusTasks(*factory, missedDeadlineFunc, pusTasks); - - std::vector pstTasks; - createPstTasks(*factory, missedDeadlineFunc, pstTasks); + std::vector pstTasks; + createPstTasks(*factory, missedDeadlineFunc, pstTasks); #if OBSW_ADD_TEST_CODE == 1 - std::vector testTasks; - createTestTasks(*factory, missedDeadlineFunc, pstTasks); + std::vector testTasks; + createTestTasks(*factory, missedDeadlineFunc, pstTasks); #endif /* OBSW_ADD_TEST_CODE == 1 */ - auto taskStarter = [](std::vector& taskVector, std::string name) { - for(const auto& task: taskVector) { - if(task != nullptr) { - task->startTask(); - } - else { - sif::error << "Task in vector " << name << " is invalid!" << std::endl; - } - } - }; + auto taskStarter = [](std::vector& taskVector, std::string name) { + for (const auto& task : taskVector) { + if (task != nullptr) { + task->startTask(); + } else { + sif::error << "Task in vector " << name << " is invalid!" << std::endl; + } + } + }; - sif::info << "Starting tasks.." << std::endl; - tmTcDistributor->startTask(); - udpBridgeTask->startTask(); - udpPollingTask->startTask(); + sif::info << "Starting tasks.." << std::endl; + tmTcDistributor->startTask(); + tmtcBridgeTask->startTask(); + tmtcPollingTask->startTask(); - taskStarter(pusTasks, "PUS Tasks"); + taskStarter(pusTasks, "PUS Tasks"); #if OBSW_ADD_TEST_CODE == 1 - taskStarter(testTasks, "Test Tasks"); + taskStarter(testTasks, "Test Tasks"); #endif /* OBSW_ADD_TEST_CODE == 1 */ - taskStarter(pstTasks, "PST Tasks"); + taskStarter(pstTasks, "PST Tasks"); #if OBSW_ADD_TEST_PST == 1 - if(startTestPst) { - pstTestTask->startTask(); - } + if (startTestPst) { + pstTestTask->startTask(); + } #endif /* RPI_TEST_ACS_BOARD == 1 */ - sif::info << "Tasks started.." << std::endl; + sif::info << "Tasks started.." << std::endl; } void initmission::createPusTasks(TaskFactory& factory, - TaskDeadlineMissedFunction missedDeadlineFunc, std::vector& taskVec) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - PeriodicTaskIF* pusVerification = factory.createPeriodicTask( - "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - taskVec.push_back(pusVerification); + TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + PeriodicTaskIF* pusVerification = factory.createPeriodicTask( + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + taskVec.push_back(pusVerification); - PeriodicTaskIF* pusEvents = factory.createPeriodicTask( - "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); - } - result = pusEvents->addComponent(objects::EVENT_MANAGER); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER); - } - taskVec.push_back(pusEvents); + PeriodicTaskIF* pusEvents = factory.createPeriodicTask( + "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); + } + result = pusEvents->addComponent(objects::EVENT_MANAGER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER); + } + taskVec.push_back(pusEvents); - PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask( - "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); - } - result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); - } - taskVec.push_back(pusHighPrio); + PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask( + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); + } + result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); + } + taskVec.push_back(pusHighPrio); - PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask( - "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); - result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT); - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS3", objects::PUS_SERVICE_3_HOUSEKEEPING); - } - taskVec.push_back(pusMedPrio); + PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask( + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS3", objects::PUS_SERVICE_3_HOUSEKEEPING); + } + taskVec.push_back(pusMedPrio); - PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask( - "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); - result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); - } - result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("INT_ERR_RPRT", - objects::INTERNAL_ERROR_REPORTER); - } - taskVec.push_back(pusLowPrio); + PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); + } + result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("INT_ERR_RPRT", objects::INTERNAL_ERROR_REPORTER); + } + taskVec.push_back(pusLowPrio); } void initmission::createPstTasks(TaskFactory& factory, - TaskDeadlineMissedFunction missedDeadlineFunc, std::vector &taskVec) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; #if OBSW_ADD_SPI_TEST_CODE == 0 - FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask( - "SPI_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, - missedDeadlineFunc); - result = pst::pstSpi(spiPst); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; - } - taskVec.push_back(spiPst); + FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask( + "SPI_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, missedDeadlineFunc); + result = pst::pstSpi(spiPst); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; + } + taskVec.push_back(spiPst); #endif } void initmission::createTestTasks(TaskFactory& factory, - TaskDeadlineMissedFunction missedDeadlineFunc, - std::vector &taskVec) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - PeriodicTaskIF* testTask = factory.createPeriodicTask( - "TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = testTask->addComponent(objects::TEST_TASK); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); - } -#if RPI_ADD_SPI_TEST == 1 - result = testTask->addComponent(objects::SPI_TEST); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST); - } + TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + PeriodicTaskIF* testTask = factory.createPeriodicTask( + "TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + result = testTask->addComponent(objects::TEST_TASK); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + } +#if OBSW_ADD_SPI_TEST_CODE == 1 + result = testTask->addComponent(objects::SPI_TEST); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST); + } #endif /* RPI_ADD_SPI_TEST == 1 */ #if RPI_ADD_GPIO_TEST == 1 - result = testTask->addComponent(objects::LIBGPIOD_TEST); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); - } + result = testTask->addComponent(objects::LIBGPIOD_TEST); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); + } #endif /* RPI_ADD_GPIO_TEST == 1 */ -#if RPI_ADD_UART_TEST == 1 - result = testTask->addComponent(objects::UART_TEST); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("UART_TEST", objects::UART_TEST); - } +#if OBSW_ADD_UART_TEST_CODE == 1 + result = testTask->addComponent(objects::UART_TEST); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("UART_TEST", objects::UART_TEST); + } #endif /* RPI_ADD_GPIO_TEST == 1 */ + taskVec.push_back(testTask); - bool startTestPst = true; - static_cast(startTestPst); + bool startTestPst = true; + static_cast(startTestPst); #if OBSW_ADD_TEST_PST == 1 - FixedTimeslotTaskIF* pstTestTask = factory->createFixedTimeslotTask("TEST_PST", 50, - PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc); - result = pst::pstTest(pstTestTask); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::info << "initmission::initTasks: ACS PST empty or invalid" << std::endl; - startTestPst = false; - } + FixedTimeslotTaskIF* pstTestTask = factory->createFixedTimeslotTask( + "TEST_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc); + result = pst::pstTest(pstTestTask); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::info << "initmission::initTasks: ACS PST empty or invalid" << std::endl; + startTestPst = false; + } #endif /* RPI_TEST_ACS_BOARD == 1 */ - } diff --git a/bsp_linux_board/InitMission.h b/bsp_linux_board/InitMission.h index f5da5855..f14135dd 100644 --- a/bsp_linux_board/InitMission.h +++ b/bsp_linux_board/InitMission.h @@ -1,9 +1,10 @@ #ifndef BSP_LINUX_INITMISSION_H_ #define BSP_LINUX_INITMISSION_H_ -#include "fsfw/tasks/Typedef.h" #include +#include "fsfw/tasks/Typedef.h" + class PeriodicTaskIF; class TaskFactory; @@ -11,14 +12,12 @@ namespace initmission { void initMission(); void initTasks(); -void createPstTasks(TaskFactory& factory, - TaskDeadlineMissedFunction missedDeadlineFunc, - std::vector &taskVec); -void createTestTasks(TaskFactory& factory, - TaskDeadlineMissedFunction missedDeadlineFunc, - std::vector &taskVec); +void createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec); +void createTestTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec); void createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, - std::vector& taskVec); -}; + std::vector& taskVec); +}; // namespace initmission #endif /* BSP_LINUX_INITMISSION_H_ */ diff --git a/bsp_linux_board/ObjectFactory.cpp b/bsp_linux_board/ObjectFactory.cpp index 5cd52c91..18da8896 100644 --- a/bsp_linux_board/ObjectFactory.cpp +++ b/bsp_linux_board/ObjectFactory.cpp @@ -1,236 +1,230 @@ -#include #include "ObjectFactory.h" -#include "objects/systemObjectList.h" +#include "OBSWConfig.h" +#include "devConf.h" #include "devices/addresses.h" #include "devices/gpioIds.h" -#include "OBSWConfig.h" -#include "tmtc/apid.h" -#include "tmtc/pusIds.h" +#include "fsfw/datapoollocal/LocalDataPoolManager.h" +#include "fsfw/tasks/TaskFactory.h" +#include "fsfw/tmtcpacket/pus/tm.h" +#include "fsfw/tmtcservices/CommandingServiceBase.h" +#include "fsfw/tmtcservices/PusServiceBase.h" #include "linux/boardtest/LibgpiodTest.h" #include "linux/boardtest/SpiTestClass.h" #include "linux/boardtest/UartTestClass.h" - #include "mission/core/GenericFactory.h" +#include "mission/devices/GPSHyperionHandler.h" +#include "mission/devices/GyroADIS1650XHandler.h" #include "mission/utility/TmFunnel.h" -#include -#include "mission/devices/GyroADIS16507Handler.h" - -#include "fsfw/datapoollocal/LocalDataPoolManager.h" -#include "fsfw/tmtcservices/CommandingServiceBase.h" -#include "fsfw/tmtcservices/PusServiceBase.h" -#include "fsfw/tmtcpacket/pus/tm.h" -#include "fsfw/tasks/TaskFactory.h" +#include "objects/systemObjectList.h" +#include "tmtc/apid.h" +#include "tmtc/pusIds.h" /* UDP server includes */ #if OBSW_USE_TMTC_TCP_BRIDGE == 1 #include #include #else -#include "fsfw/osal/common/UdpTmTcBridge.h" #include "fsfw/osal/common/UdpTcPollingTask.h" +#include "fsfw/osal/common/UdpTmTcBridge.h" #endif -#include "fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h" -#include "fsfw_hal/devicehandlers/MgmRM3100Handler.h" -#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h" -#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" -#include "fsfw_hal/linux/rpi/GpioRPi.h" -#include "fsfw_hal/common/gpio/GpioCookie.h" -#include "fsfw_hal/linux/spi/SpiCookie.h" -#include "fsfw_hal/linux/spi/SpiComIF.h" #include #include +#include "fsfw_hal/common/gpio/GpioCookie.h" +#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h" +#include "fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h" +#include "fsfw_hal/devicehandlers/MgmRM3100Handler.h" +#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" +#include "fsfw_hal/linux/rpi/GpioRPi.h" +#include "fsfw_hal/linux/spi/SpiComIF.h" +#include "fsfw_hal/linux/spi/SpiCookie.h" + void Factory::setStaticFrameworkObjectIds() { - PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; - PusServiceBase::packetDestination = objects::TM_FUNNEL; + PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; + PusServiceBase::packetDestination = objects::TM_FUNNEL; - CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; - CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; + CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; + CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; - TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; - // No storage object for now. - TmFunnel::storageDestination = objects::NO_OBJECT; + TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; + // No storage object for now. + TmFunnel::storageDestination = objects::NO_OBJECT; - VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION; - TmPacketBase::timeStamperId = objects::TIME_STAMPER; + VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION; + TmPacketBase::timeStamperId = objects::TIME_STAMPER; } +void ObjectFactory::produce(void* args) { + Factory::setStaticFrameworkObjectIds(); + ObjectFactory::produceGenericObjects(); + GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF); + GpioCookie* gpioCookie = nullptr; + static_cast(gpioCookie); -void ObjectFactory::produce(void* args){ - Factory::setStaticFrameworkObjectIds(); - ObjectFactory::produceGenericObjects(); + new SpiComIF(objects::SPI_COM_IF, gpioIF); -#if OBSW_USE_TMTC_TCP_BRIDGE == 1 - auto tmtcBridge = new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); - tmtcBridge->setMaxNumberOfPacketsStored(50); - new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); -#else - auto tmtcBridge = new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); - tmtcBridge->setMaxNumberOfPacketsStored(50); - new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); -#endif - - GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF); - GpioCookie* gpioCookie = nullptr; - static_cast(gpioCookie); - - new SpiComIF(objects::SPI_COM_IF, gpioIF); - - std::string spiDev; - SpiCookie* spiCookie = nullptr; - static_cast(spiCookie); + std::string spiDev; + SpiCookie* spiCookie = nullptr; + static_cast(spiCookie); #if OBSW_ADD_ACS_BOARD == 1 - if(gpioCookie == nullptr) { - gpioCookie = new GpioCookie(); - } - // TODO: Missing pin for Gyro 2 - gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_0_LIS3_CS, gpio::MGM_0_BCM_PIN, - "MGM_0_LIS3", gpio::Direction::OUT, 1); - gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_1_RM3100_CS, gpio::MGM_1_BCM_PIN, - "MGM_1_RM3100", gpio::Direction::OUT, 1); - gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_2_LIS3_CS, gpio::MGM_2_BCM_PIN, - "MGM_2_LIS3", gpio::Direction::OUT, 1); - gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_3_RM3100_CS, gpio::MGM_3_BCM_PIN, - "MGM_3_RM3100", gpio::Direction::OUT, 1); - gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN, - "GYRO_0_ADIS", gpio::Direction::OUT, 1); - gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_1_L3G_CS, gpio::GYRO_1_BCM_PIN, - "GYRO_1_L3G", gpio::Direction::OUT, 1); - gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_2_ADIS_CS, gpio::GYRO_2_BCM_PIN, - "GYRO_2_ADIS", gpio::Direction::OUT, 1); - gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_3_L3G_CS, gpio::GYRO_3_BCM_PIN, - "GYRO_3_L3G", gpio::Direction::OUT, 1); - gpioIF->addGpios(gpioCookie); + if (gpioCookie == nullptr) { + gpioCookie = new GpioCookie(); + } + // TODO: Missing pin for Gyro 2 + gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_0_LIS3_CS, gpio::MGM_0_BCM_PIN, "MGM_0_LIS3", + gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_1_RM3100_CS, gpio::MGM_1_BCM_PIN, + "MGM_1_RM3100", gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_2_LIS3_CS, gpio::MGM_2_BCM_PIN, "MGM_2_LIS3", + gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_3_RM3100_CS, gpio::MGM_3_BCM_PIN, + "MGM_3_RM3100", gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN, + "GYRO_0_ADIS", gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_1_L3G_CS, gpio::GYRO_1_BCM_PIN, "GYRO_1_L3G", + gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_2_ADIS_CS, gpio::GYRO_2_BCM_PIN, + "GYRO_2_ADIS", gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_3_L3G_CS, gpio::GYRO_3_BCM_PIN, "GYRO_3_L3G", + gpio::Direction::OUT, 1); + gpioIF->addGpios(gpioCookie); - spiDev = "/dev/spidev0.1"; - spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev, - MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); - auto mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_0_LIS3_HANDLER, - objects::SPI_COM_IF, spiCookie, 0); - mgmLis3Handler->setStartUpImmediately(); + spiDev = "/dev/spidev0.1"; + spiCookie = + new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev, + MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); + auto mgmLis3Handler = + new MgmLIS3MDLHandler(objects::MGM_0_LIS3_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + mgmLis3Handler->setStartUpImmediately(); #if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 - mgmLis3Handler->setToGoToNormalMode(true); + mgmLis3Handler->setToGoToNormalMode(true); #endif - spiCookie = new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev, - RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); - auto mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_1_RM3100_HANDLER, - objects::SPI_COM_IF, spiCookie, 0); - mgmRm3100Handler->setStartUpImmediately(); + spiCookie = + new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev, + RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); + auto mgmRm3100Handler = + new MgmRM3100Handler(objects::MGM_1_RM3100_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + mgmRm3100Handler->setStartUpImmediately(); #if FSFW_HAL_RM3100_MGM_DEBUG == 1 - mgmRm3100Handler->setToGoToNormalMode(true); + mgmRm3100Handler->setToGoToNormalMode(true); #endif - spiCookie = new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, spiDev, - MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); - mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, - objects::SPI_COM_IF, spiCookie, 0); - mgmLis3Handler->setStartUpImmediately(); + spiCookie = + new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, spiDev, + MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); + mgmLis3Handler = + new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + mgmLis3Handler->setStartUpImmediately(); #if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 - mgmLis3Handler->setToGoToNormalMode(true); + mgmLis3Handler->setToGoToNormalMode(true); #endif - spiCookie = new SpiCookie(addresses::MGM_3_RM3100, gpioIds::MGM_3_RM3100_CS, spiDev, - RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); - mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_3_RM3100_HANDLER, - objects::SPI_COM_IF, spiCookie, 0); - mgmRm3100Handler->setStartUpImmediately(); + spiCookie = + new SpiCookie(addresses::MGM_3_RM3100, gpioIds::MGM_3_RM3100_CS, spiDev, + RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); + mgmRm3100Handler = + new MgmRM3100Handler(objects::MGM_3_RM3100_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + mgmRm3100Handler->setStartUpImmediately(); #if FSFW_HAL_RM3100_MGM_DEBUG == 1 - mgmRm3100Handler->setToGoToNormalMode(true); + mgmRm3100Handler->setToGoToNormalMode(true); #endif - spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev, - ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); - auto adisHandler = new GyroADIS16507Handler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, - spiCookie); - adisHandler->setStartUpImmediately(); - spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev, - L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); - auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF, - spiCookie, 0); - gyroL3gHandler->setStartUpImmediately(); -#if FSFW_HAL_L3GD20_GYRO_DEBUG== 1 - gyroL3gHandler->setToGoToNormalMode(true); + spiCookie = + new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev, + ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); + auto adisHandler = + new GyroADIS16507Handler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, spiCookie); + adisHandler->setStartUpImmediately(); + spiCookie = + new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev, L3GD20H::MAX_BUFFER_SIZE, + spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); + auto gyroL3gHandler = + new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + gyroL3gHandler->setStartUpImmediately(); +#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1 + gyroL3gHandler->setToGoToNormalMode(true); #endif - spiCookie = new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev, - ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); - adisHandler = new GyroADIS16507Handler(objects::GYRO_2_ADIS_HANDLER, objects::SPI_COM_IF, - spiCookie); - adisHandler->setStartUpImmediately(); + spiCookie = + new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev, + ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); + adisHandler = + new GyroADIS16507Handler(objects::GYRO_2_ADIS_HANDLER, objects::SPI_COM_IF, spiCookie); + adisHandler->setStartUpImmediately(); - spiCookie = new SpiCookie(addresses::GYRO_3_L3G, gpioIds::GYRO_3_L3G_CS, spiDev, - L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); - gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_3_L3G_HANDLER, objects::SPI_COM_IF, - spiCookie, 0); - gyroL3gHandler->setStartUpImmediately(); -#if FSFW_HAL_L3GD20_GYRO_DEBUG== 1 - gyroL3gHandler->setToGoToNormalMode(true); + spiCookie = + new SpiCookie(addresses::GYRO_3_L3G, gpioIds::GYRO_3_L3G_CS, spiDev, L3GD20H::MAX_BUFFER_SIZE, + spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); + gyroL3gHandler = + new GyroHandlerL3GD20H(objects::GYRO_3_L3G_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + gyroL3gHandler->setStartUpImmediately(); +#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1 + gyroL3gHandler->setToGoToNormalMode(true); #endif #endif /* RPI_TEST_ACS_BOARD == 1 */ #if OBSW_ADD_TEST_CODE == 1 - createTestTasks(); + createTestTasks(); #endif /* OBSW_ADD_TEST_CODE == 1 */ } void ObjectFactory::createTestTasks() { + new TestTask(objects::TEST_TASK); - new TestTask(objects::TEST_TASK); - -#if RPI_ADD_SPI_TEST == 1 - new SpiTestClass(objects::SPI_TEST, gpioIF); +#if OBSW_ADD_SPI_TEST_CODE == 1 + new SpiTestClass(objects::SPI_TEST, gpioIF); #endif -#if RPI_ADD_UART_TEST == 1 - new UartTestClass(objects::UART_TEST); +#if OBSW_ADD_UART_TEST_CODE == 1 + new UartTestClass(objects::UART_TEST); #else - new UartComIF(objects::UART_COM_IF); + new UartComIF(objects::UART_COM_IF); #endif #if RPI_LOOPBACK_TEST_GPIO == 1 - GpioCookie* gpioCookieLoopback = new GpioCookie(); - /* Loopback pins. Adapt according to setup */ - gpioId_t gpioIdSender = gpioIds::TEST_ID_0; - int bcmPinSender = 26; - gpioId_t gpioIdReader = gpioIds::TEST_ID_1; - int bcmPinReader = 16; - gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER", - gpio::Direction::OUT, 0); - gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdReader, bcmPinReader, "GPIO_LB_READER", - gpio::Direction::IN, 0); - new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookieLoopback); + GpioCookie* gpioCookieLoopback = new GpioCookie(); + /* Loopback pins. Adapt according to setup */ + gpioId_t gpioIdSender = gpioIds::TEST_ID_0; + int bcmPinSender = 26; + gpioId_t gpioIdReader = gpioIds::TEST_ID_1; + int bcmPinReader = 16; + gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER", + gpio::Direction::OUT, 0); + gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdReader, bcmPinReader, "GPIO_LB_READER", + gpio::Direction::IN, 0); + new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookieLoopback); #endif /* RPI_LOOPBACK_TEST_GPIO == 1 */ #if RPI_TEST_ADIS16507 == 1 - if(gpioCookie == nullptr) { - gpioCookie = new GpioCookie(); - } - gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN, - "GYRO_0_ADIS", gpio::Direction::OUT, 1); - gpioIF->addGpios(gpioCookie); + if (gpioCookie == nullptr) { + gpioCookie = new GpioCookie(); + } + gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN, + "GYRO_0_ADIS", gpio::Direction::OUT, 1); + gpioIF->addGpios(gpioCookie); - spiDev = "/dev/spidev0.1"; - spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev, - ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, spi::DEFAULT_ADIS16507_SPEED, - nullptr, nullptr); - auto adisGyroHandler = new GyroADIS16507Handler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, spiCookie); - adisGyroHandler->setStartUpImmediately(); + spiDev = "/dev/spidev0.1"; + spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev, + ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, + spi::DEFAULT_ADIS16507_SPEED, nullptr, nullptr); + auto adisGyroHandler = + new GyroADIS16507Handler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, spiCookie); + adisGyroHandler->setStartUpImmediately(); #endif /* RPI_TEST_ADIS16507 == 1 */ #if RPI_TEST_GPS_HANDLER == 1 - UartCookie* uartCookie = new UartCookie(objects::GPS0_HANDLER, "/dev/serial0", - UartModes::CANONICAL, 9600, 1024); - uartCookie->setToFlushInput(true); - uartCookie->setReadCycles(6); - GPSHyperionHandler* gpsHandler = new GPSHyperionHandler(objects::GPS0_HANDLER, - objects::UART_COM_IF, uartCookie, false); - gpsHandler->setStartUpImmediately(); + UartCookie* uartCookie = + new UartCookie(objects::GPS0_HANDLER, "/dev/serial0", UartModes::CANONICAL, 9600, 1024); + uartCookie->setToFlushInput(true); + uartCookie->setReadCycles(6); + GPSHyperionHandler* gpsHandler = + new GPSHyperionHandler(objects::GPS0_HANDLER, objects::UART_COM_IF, uartCookie, false); + gpsHandler->setStartUpImmediately(); #endif - } diff --git a/bsp_linux_board/ObjectFactory.h b/bsp_linux_board/ObjectFactory.h index 3b9aca49..909baf06 100644 --- a/bsp_linux_board/ObjectFactory.h +++ b/bsp_linux_board/ObjectFactory.h @@ -1,12 +1,11 @@ #ifndef BSP_LINUX_OBJECTFACTORY_H_ #define BSP_LINUX_OBJECTFACTORY_H_ - namespace ObjectFactory { - void setStatics(); - void produce(void* args); +void setStatics(); +void produce(void* args); - void createTestTasks(); -}; +void createTestTasks(); +}; // namespace ObjectFactory #endif /* BSP_LINUX_OBJECTFACTORY_H_ */ diff --git a/bsp_linux_board/boardconfig/CMakeLists.txt b/bsp_linux_board/boardconfig/CMakeLists.txt index 67fbaf88..f9136e3e 100644 --- a/bsp_linux_board/boardconfig/CMakeLists.txt +++ b/bsp_linux_board/boardconfig/CMakeLists.txt @@ -1,7 +1,7 @@ -target_sources(${TARGET_NAME} PRIVATE +target_sources(${OBSW_NAME} PRIVATE print.c ) -target_include_directories(${TARGET_NAME} PUBLIC +target_include_directories(${OBSW_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/bsp_linux_board/boardconfig/etl_profile.h b/bsp_linux_board/boardconfig/etl_profile.h index c35ffb46..54aca344 100644 --- a/bsp_linux_board/boardconfig/etl_profile.h +++ b/bsp_linux_board/boardconfig/etl_profile.h @@ -32,7 +32,7 @@ SOFTWARE. #define ETL_CHECK_PUSH_POP -#define ETL_CPP11_SUPPORTED 1 -#define ETL_NO_NULLPTR_SUPPORT 0 +#define ETL_CPP11_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 #endif diff --git a/bsp_linux_board/boardconfig/gcov.h b/bsp_linux_board/boardconfig/gcov.h index 491d24c6..80acdd86 100644 --- a/bsp_linux_board/boardconfig/gcov.h +++ b/bsp_linux_board/boardconfig/gcov.h @@ -6,8 +6,9 @@ extern "C" void __gcov_flush(); #else void __gcov_flush() { - sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if " - "coverage information is desired.\n" << std::flush; + sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if " + "coverage information is desired.\n" + << std::flush; } #endif diff --git a/bsp_linux_board/boardconfig/print.c b/bsp_linux_board/boardconfig/print.c index c501e0b7..c2b2e15d 100644 --- a/bsp_linux_board/boardconfig/print.c +++ b/bsp_linux_board/boardconfig/print.c @@ -1,14 +1,10 @@ -#include +#include #include void printChar(const char* character, bool errStream) { - if(errStream) { - putc(*character, stderr); - return; - } - putc(*character, stdout); + if (errStream) { + putc(*character, stderr); + return; + } + putc(*character, stdout); } - - - - diff --git a/bsp_linux_board/boardtest/CMakeLists.txt b/bsp_linux_board/boardtest/CMakeLists.txt index 0599b73f..fe4910f2 100644 --- a/bsp_linux_board/boardtest/CMakeLists.txt +++ b/bsp_linux_board/boardtest/CMakeLists.txt @@ -1,4 +1,4 @@ -target_sources(${TARGET_NAME} PRIVATE +target_sources(${OBSW_NAME} PRIVATE ) diff --git a/bsp_linux_board/main.cpp b/bsp_linux_board/main.cpp index a766f2a0..2f8ac4bc 100644 --- a/bsp_linux_board/main.cpp +++ b/bsp_linux_board/main.cpp @@ -1,11 +1,10 @@ +#include + #include "InitMission.h" #include "OBSWConfig.h" #include "OBSWVersion.h" - -#include "fsfw/FSFWVersion.h" #include "fsfw/tasks/TaskFactory.h" - -#include +#include "fsfw/version.h" #ifdef RASPBERRY_PI static const char* const BOARD_NAME = "Raspberry Pi"; @@ -19,21 +18,17 @@ static const char* const BOARD_NAME = "Unknown Board"; * @brief This is the main program and entry point for the Raspberry Pi. * @return */ -int main(void) -{ - std::cout << "-- EIVE OBSW --" << std::endl; - std::cout << "-- Compiled for Linux board " << BOARD_NAME << " --" << std::endl; - std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << - "." << SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << - FSFW_REVISION << "--" << std::endl; - std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; +int main(void) { + std::cout << "-- EIVE OBSW --" << std::endl; + std::cout << "-- Compiled for Linux board " << BOARD_NAME << " --" << std::endl; + std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << "." + << SW_REVISION << ", FSFW v" << fsfw::FSFW_VERSION << "--" << std::endl; + std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; - initmission::initMission(); + initmission::initMission(); - for(;;) { - /* Suspend main thread by sleeping it. */ - TaskFactory::delayTask(5000); - } + for (;;) { + /* Suspend main thread by sleeping it. */ + TaskFactory::delayTask(5000); + } } - - diff --git a/bsp_q7s/CMakeLists.txt b/bsp_q7s/CMakeLists.txt index b2c24d5f..459ead8a 100644 --- a/bsp_q7s/CMakeLists.txt +++ b/bsp_q7s/CMakeLists.txt @@ -1,17 +1,25 @@ -target_sources(${TARGET_NAME} PUBLIC +#simple mode +add_executable(${SIMPLE_OBSW_NAME} EXCLUDE_FROM_ALL) +target_compile_definitions(${SIMPLE_OBSW_NAME} PRIVATE "Q7S_SIMPLE_MODE") +target_sources(${SIMPLE_OBSW_NAME} PUBLIC + main.cpp +) +#I think this is unintentional? (produces linker errors for stuff in /linux) +target_link_libraries(${SIMPLE_OBSW_NAME} PUBLIC + ${LIB_FSFW_NAME} +) +target_compile_definitions(${SIMPLE_OBSW_NAME} PRIVATE "Q7S_SIMPLE_MODE") +add_subdirectory(simple) + +target_sources(${OBSW_NAME} PUBLIC main.cpp ) add_subdirectory(boardtest) -if(Q7S_SIMPLE_MODE) - add_subdirectory(simple) -else() - add_subdirectory(boardconfig) - add_subdirectory(comIF) - add_subdirectory(gpio) - add_subdirectory(core) - add_subdirectory(memory) - add_subdirectory(callbacks) - add_subdirectory(devices) -endif() +add_subdirectory(boardconfig) +add_subdirectory(comIF) +add_subdirectory(core) +add_subdirectory(memory) +add_subdirectory(callbacks) +add_subdirectory(xadc) diff --git a/bsp_q7s/boardconfig/CMakeLists.txt b/bsp_q7s/boardconfig/CMakeLists.txt index 67fbaf88..feefbe5a 100644 --- a/bsp_q7s/boardconfig/CMakeLists.txt +++ b/bsp_q7s/boardconfig/CMakeLists.txt @@ -1,7 +1,12 @@ -target_sources(${TARGET_NAME} PRIVATE +target_sources(${OBSW_NAME} PRIVATE print.c ) -target_include_directories(${TARGET_NAME} PUBLIC +target_sources(${SIMPLE_OBSW_NAME} PRIVATE + print.c +) + + +target_include_directories(${OBSW_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index 34516fa6..5c52693c 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -3,74 +3,101 @@ namespace q7s { -static constexpr char SPI_DEFAULT_DEV[] = "/dev/spidev2.0"; -static constexpr char SPI_RW_DEV[] = "/dev/spidev3.0"; +static constexpr char SPI_DEFAULT_DEV[] = "/dev/spi-main"; +static constexpr char SPI_RW_DEV[] = "/dev/spi-rw"; -static constexpr char I2C_DEFAULT_DEV[] = "/dev/i2c-1"; +static constexpr char I2C_DEFAULT_DEV[] = "/dev/i2c-eive"; -static constexpr char UART_GNSS_DEV[] = "/dev/ttyUL0"; -static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ttyUL2"; -static constexpr char UART_PLOC_SUPERVSIOR_DEV[] = "/dev/ttyUL3"; -static constexpr char UART_SYRLINKS_DEV[] = "/dev/ttyUL4"; -static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ttyUL7"; +static constexpr char UART_GNSS_DEV[] = "/dev/ul-gps"; +static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ul-plmpsoc"; +static constexpr char UART_PLOC_SUPERVSIOR_DEV[] = "/dev/ul-plsv"; +static constexpr char UART_SYRLINKS_DEV[] = "/dev/ul-syrlinks"; +static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ul-str"; static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio0"; static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio2"; static constexpr char UIO_PDEC_RAM[] = "/dev/uio3"; +static constexpr char UIO_PTME[] = "/dev/uio1"; +static constexpr int MAP_ID_PTME_CONFIG = 3; + +namespace uiomapids { +static const int PTME_VC0 = 0; +static const int PTME_VC1 = 1; +static const int PTME_VC2 = 2; +static const int PTME_VC3 = 3; +static const int PTME_CONFIG = 4; +} // namespace uiomapids namespace gpioNames { - static constexpr char GYRO_0_ADIS_CS[] = "gyro_0_adis_chip_select"; - static constexpr char GYRO_1_L3G_CS[] = "gyro_1_l3g_chip_select"; - static constexpr char GYRO_2_ADIS_CS[] = "gyro_2_adis_chip_select"; - static constexpr char GYRO_3_L3G_CS[] = "gyro_3_l3g_chip_select"; - static constexpr char MGM_0_CS[] = "mgm_0_lis3_chip_select"; - static constexpr char MGM_1_CS[] = "mgm_1_rm3100_chip_select"; - static constexpr char MGM_2_CS[] = "mgm_2_lis3_chip_select"; - static constexpr char MGM_3_CS[] = "mgm_3_rm3100_chip_select"; - static constexpr char RESET_GNSS_0[] = "reset_gnss_0"; - static constexpr char RESET_GNSS_1[] = "reset_gnss_1"; - static constexpr char GNSS_0_ENABLE[] = "enable_gnss_0"; - static constexpr char GNSS_1_ENABLE[] = "enable_gnss_1"; - static constexpr char GYRO_0_ENABLE[] = "enable_gyro_0"; - static constexpr char GYRO_2_ENABLE[] = "enable_gyro_2"; - static constexpr char HEATER_0[] = "heater0"; - static constexpr char HEATER_1[] = "heater1"; - static constexpr char HEATER_2[] = "heater2"; - static constexpr char HEATER_3[] = "heater3"; - static constexpr char HEATER_4[] = "heater4"; - static constexpr char HEATER_5[] = "heater5"; - static constexpr char HEATER_6[] = "heater6"; - static constexpr char HEATER_7[] = "heater7"; - static constexpr char SA_DPL_PIN_0[] = "sa_dpl_0"; - static constexpr char SA_DPL_PIN_1[] = "sa_dpl_1"; - static constexpr char SPI_MUX_BIT_1_PIN[] = "spi_mux_bit_1"; - static constexpr char SPI_MUX_BIT_2_PIN[] = "spi_mux_bit_2"; - static constexpr char SPI_MUX_BIT_3_PIN[] = "spi_mux_bit_3"; - static constexpr char SPI_MUX_BIT_4_PIN[] = "spi_mux_bit_4"; - static constexpr char SPI_MUX_BIT_5_PIN[] = "spi_mux_bit_5"; - static constexpr char SPI_MUX_BIT_6_PIN[] = "spi_mux_bit_6"; - static constexpr char EN_RW_CS[] = "en_rw_cs"; - static constexpr char EN_RW_1[] = "enable_rw_1"; - static constexpr char EN_RW_2[] = "enable_rw_2"; - static constexpr char EN_RW_3[] = "enable_rw_3"; - static constexpr char EN_RW_4[] = "enable_rw_4"; - static constexpr char GNSS_MUX_SELECT[] = "gnss_mux_select"; - static constexpr char RAD_SENSOR_CHIP_SELECT[] = "rad_sensor_chip_select"; - static constexpr char PAPB_BUSY_SIGNAL_VC0[] = "papb_busy_signal_vc0"; - static constexpr char PAPB_EMPTY_SIGNAL_VC0[] = "papb_empty_signal_vc0"; - static constexpr char PAPB_BUSY_SIGNAL_VC1[] = "papb_busy_signal_vc1"; - static constexpr char PAPB_EMPTY_SIGNAL_VC1[] = "papb_empty_signal_vc1"; - static constexpr char PAPB_BUSY_SIGNAL_VC2[] = "papb_busy_signal_vc2"; - static constexpr char PAPB_EMPTY_SIGNAL_VC2[] = "papb_empty_signal_vc2"; - static constexpr char PAPB_BUSY_SIGNAL_VC3[] = "papb_busy_signal_vc3"; - static constexpr char PAPB_EMPTY_SIGNAL_VC3[] = "papb_empty_signal_vc3"; - static constexpr char RS485_EN_TX_CLOCK[] = "tx_clock_enable_ltc2872"; - static constexpr char RS485_EN_TX_DATA[] = "tx_data_enable_ltc2872"; - static constexpr char RS485_EN_RX_CLOCK[] = "rx_clock_enable_ltc2872"; - static constexpr char RS485_EN_RX_DATA[] = "rx_data_enable_ltc2872"; - static constexpr char PDEC_RESET[] = "pdec_reset"; - static constexpr char BIT_RATE_SEL[] = "bit_rate_sel"; -} -} + +static constexpr char GYRO_0_ADIS_CS[] = "gyro_0_adis_chip_select"; +static constexpr char GYRO_1_L3G_CS[] = "gyro_1_l3g_chip_select"; +static constexpr char GYRO_2_ADIS_CS[] = "gyro_2_adis_chip_select"; +static constexpr char GYRO_3_L3G_CS[] = "gyro_3_l3g_chip_select"; +static constexpr char MGM_0_CS[] = "mgm_0_lis3_chip_select"; +static constexpr char MGM_1_CS[] = "mgm_1_rm3100_chip_select"; +static constexpr char MGM_2_CS[] = "mgm_2_lis3_chip_select"; +static constexpr char MGM_3_CS[] = "mgm_3_rm3100_chip_select"; +static constexpr char RESET_GNSS_0[] = "reset_gnss_0"; +static constexpr char RESET_GNSS_1[] = "reset_gnss_1"; +static constexpr char GNSS_0_ENABLE[] = "enable_gnss_0"; +static constexpr char GNSS_1_ENABLE[] = "enable_gnss_1"; +static constexpr char GYRO_0_ENABLE[] = "enable_gyro_0"; +static constexpr char GYRO_2_ENABLE[] = "enable_gyro_2"; +static constexpr char GNSS_SELECT[] = "gnss_mux_select"; +static constexpr char GNSS_MUX_SELECT[] = "gnss_mux_select"; + +static constexpr char HEATER_0[] = "heater0"; +static constexpr char HEATER_1[] = "heater1"; +static constexpr char HEATER_2[] = "heater2"; +static constexpr char HEATER_3[] = "heater3"; +static constexpr char HEATER_4[] = "heater4"; +static constexpr char HEATER_5[] = "heater5"; +static constexpr char HEATER_6[] = "heater6"; +static constexpr char HEATER_7[] = "heater7"; +static constexpr char SA_DPL_PIN_0[] = "sa_dpl_0"; +static constexpr char SA_DPL_PIN_1[] = "sa_dpl_1"; +static constexpr char SPI_MUX_BIT_0_PIN[] = "spi_mux_bit_0"; +static constexpr char SPI_MUX_BIT_1_PIN[] = "spi_mux_bit_1"; +static constexpr char SPI_MUX_BIT_2_PIN[] = "spi_mux_bit_2"; +static constexpr char SPI_MUX_BIT_3_PIN[] = "spi_mux_bit_3"; +static constexpr char SPI_MUX_BIT_4_PIN[] = "spi_mux_bit_4"; +static constexpr char SPI_MUX_BIT_5_PIN[] = "spi_mux_bit_5"; +static constexpr char EN_RW_CS[] = "en_rw_cs"; +static constexpr char EN_RW_1[] = "enable_rw_1"; +static constexpr char EN_RW_2[] = "enable_rw_2"; +static constexpr char EN_RW_3[] = "enable_rw_3"; +static constexpr char EN_RW_4[] = "enable_rw_4"; + +static constexpr char RAD_SENSOR_CHIP_SELECT[] = "rad_sensor_chip_select"; +static constexpr char ENABLE_RADFET[] = "enable_radfet"; +static constexpr char PAPB_BUSY_SIGNAL_VC0[] = "papb_busy_signal_vc0"; +static constexpr char PAPB_EMPTY_SIGNAL_VC0[] = "papb_empty_signal_vc0"; +static constexpr char PAPB_BUSY_SIGNAL_VC1[] = "papb_busy_signal_vc1"; +static constexpr char PAPB_EMPTY_SIGNAL_VC1[] = "papb_empty_signal_vc1"; +static constexpr char PAPB_BUSY_SIGNAL_VC2[] = "papb_busy_signal_vc2"; +static constexpr char PAPB_EMPTY_SIGNAL_VC2[] = "papb_empty_signal_vc2"; +static constexpr char PAPB_BUSY_SIGNAL_VC3[] = "papb_busy_signal_vc3"; +static constexpr char PAPB_EMPTY_SIGNAL_VC3[] = "papb_empty_signal_vc3"; +static constexpr char RS485_EN_TX_CLOCK[] = "tx_clock_enable_ltc2872"; +static constexpr char RS485_EN_TX_DATA[] = "tx_data_enable_ltc2872"; +static constexpr char RS485_EN_RX_CLOCK[] = "rx_clock_enable_ltc2872"; +static constexpr char RS485_EN_RX_DATA[] = "rx_data_enable_ltc2872"; +static constexpr char PDEC_RESET[] = "pdec_reset"; + +static constexpr char PL_PCDU_ENABLE_VBAT0[] = "enable_plpcdu_vbat0"; +static constexpr char PL_PCDU_ENABLE_VBAT1[] = "enable_plpcdu_vbat1"; +static constexpr char PL_PCDU_ENABLE_DRO[] = "enable_plpcdu_dro"; +static constexpr char PL_PCDU_ENABLE_X8[] = "enable_plpcdu_x8"; +static constexpr char PL_PCDU_ENABLE_TX[] = "enable_plpcdu_tx"; +static constexpr char PL_PCDU_ENABLE_HPA[] = "enable_plpcdu_hpa"; +static constexpr char PL_PCDU_ENABLE_MPA[] = "enable_plpcdu_mpa"; +static constexpr char PL_PCDU_ADC_CS[] = "plpcdu_adc_chip_select"; + +static constexpr char ENABLE_SUPV_UART[] = "enable_supv_uart"; +static constexpr char ENABLE_MPSOC_UART[] = "enable_mpsoc_uart"; + +} // namespace gpioNames +} // namespace q7s #endif /* BSP_Q7S_BOARDCONFIG_BUSCONF_H_ */ diff --git a/bsp_q7s/boardconfig/etl_profile.h b/bsp_q7s/boardconfig/etl_profile.h index c35ffb46..54aca344 100644 --- a/bsp_q7s/boardconfig/etl_profile.h +++ b/bsp_q7s/boardconfig/etl_profile.h @@ -32,7 +32,7 @@ SOFTWARE. #define ETL_CHECK_PUSH_POP -#define ETL_CPP11_SUPPORTED 1 -#define ETL_NO_NULLPTR_SUPPORT 0 +#define ETL_CPP11_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 #endif diff --git a/bsp_q7s/boardconfig/gcov.h b/bsp_q7s/boardconfig/gcov.h index 491d24c6..80acdd86 100644 --- a/bsp_q7s/boardconfig/gcov.h +++ b/bsp_q7s/boardconfig/gcov.h @@ -6,8 +6,9 @@ extern "C" void __gcov_flush(); #else void __gcov_flush() { - sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if " - "coverage information is desired.\n" << std::flush; + sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if " + "coverage information is desired.\n" + << std::flush; } #endif diff --git a/bsp_q7s/boardconfig/print.c b/bsp_q7s/boardconfig/print.c index c501e0b7..3aba2d73 100644 --- a/bsp_q7s/boardconfig/print.c +++ b/bsp_q7s/boardconfig/print.c @@ -2,13 +2,9 @@ #include void printChar(const char* character, bool errStream) { - if(errStream) { - putc(*character, stderr); - return; - } - putc(*character, stdout); + if (errStream) { + putc(*character, stderr); + return; + } + putc(*character, stdout); } - - - - diff --git a/bsp_q7s/boardconfig/q7sConfig.h.in b/bsp_q7s/boardconfig/q7sConfig.h.in index 43283ea1..1dd1d85a 100644 --- a/bsp_q7s/boardconfig/q7sConfig.h.in +++ b/bsp_q7s/boardconfig/q7sConfig.h.in @@ -3,8 +3,6 @@ #include -#cmakedefine01 Q7S_SIMPLE_MODE - /*******************************************************************/ /** All of the following flags should be enabled for mission code */ /*******************************************************************/ @@ -31,6 +29,10 @@ #define Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST 0 +#ifndef Q7S_SIMPLE_MODE +#define Q7S_SIMPLE_MODE 0 +#endif + namespace config { static const uint32_t SD_CARD_ACCESS_MUTEX_TIMEOUT = 50; diff --git a/bsp_q7s/boardtest/CMakeLists.txt b/bsp_q7s/boardtest/CMakeLists.txt index 1cda38ca..29c9f1e1 100644 --- a/bsp_q7s/boardtest/CMakeLists.txt +++ b/bsp_q7s/boardtest/CMakeLists.txt @@ -1,8 +1,10 @@ -target_sources(${TARGET_NAME} PRIVATE +target_sources(${OBSW_NAME} PRIVATE FileSystemTest.cpp Q7STestTask.cpp ) - - - +if(EIVE_BUILD_Q7S_SIMPLE_MODE) + target_sources(${SIMPLE_OBSW_NAME} PRIVATE + FileSystemTest.cpp + ) +endif() \ No newline at end of file diff --git a/bsp_q7s/boardtest/FileSystemTest.cpp b/bsp_q7s/boardtest/FileSystemTest.cpp index 92c4cf3d..e1dd564d 100644 --- a/bsp_q7s/boardtest/FileSystemTest.cpp +++ b/bsp_q7s/boardtest/FileSystemTest.cpp @@ -1,26 +1,23 @@ #include "FileSystemTest.h" + +#include +#include + #include "fsfw/timemanager/Stopwatch.h" -#include -#include - -enum SdCard { - SDC0, - SDC1 -}; +enum SdCard { SDC0, SDC1 }; FileSystemTest::FileSystemTest() { - using namespace std; - SdCard sdCard = SdCard::SDC0; - cout << "SD Card Test for SD card " << static_cast(sdCard) << std::endl; - //Stopwatch stopwatch; - std::system("q7hw sd info all > /tmp/sd_status.txt"); - //stopwatch.stop(true); - std::system("q7hw sd set 0 on > /tmp/sd_set.txt"); - //stopwatch.stop(true); - std::system("q7hw sd set 0 off > /tmp/sd_set.txt"); - //stopwatch.stop(true); + using namespace std; + SdCard sdCard = SdCard::SDC0; + cout << "SD Card Test for SD card " << static_cast(sdCard) << std::endl; + // Stopwatch stopwatch; + std::system("q7hw sd info all > /tmp/sd_status.txt"); + // stopwatch.stop(true); + std::system("q7hw sd set 0 on > /tmp/sd_set.txt"); + // stopwatch.stop(true); + std::system("q7hw sd set 0 off > /tmp/sd_set.txt"); + // stopwatch.stop(true); } -FileSystemTest::~FileSystemTest() { -} +FileSystemTest::~FileSystemTest() {} diff --git a/bsp_q7s/boardtest/FileSystemTest.h b/bsp_q7s/boardtest/FileSystemTest.h index 256a0b36..bdb7989f 100644 --- a/bsp_q7s/boardtest/FileSystemTest.h +++ b/bsp_q7s/boardtest/FileSystemTest.h @@ -2,12 +2,11 @@ #define BSP_Q7S_BOARDTEST_FILESYSTEMTEST_H_ class FileSystemTest { -public: - FileSystemTest(); - virtual~ FileSystemTest(); -private: + public: + FileSystemTest(); + virtual ~FileSystemTest(); + + private: }; - - #endif /* BSP_Q7S_BOARDTEST_FILESYSTEMTEST_H_ */ diff --git a/bsp_q7s/boardtest/Q7STestTask.cpp b/bsp_q7s/boardtest/Q7STestTask.cpp index 5cead3d5..8b96450f 100644 --- a/bsp_q7s/boardtest/Q7STestTask.cpp +++ b/bsp_q7s/boardtest/Q7STestTask.cpp @@ -1,376 +1,452 @@ +#include "Q7STestTask.h" + #include #include +#include #include -#include "Q7STestTask.h" +#include +#include + +#include +#include +#include +#include +#include +#include #include "bsp_q7s/memory/SdCardManager.h" #include "bsp_q7s/memory/scratchApi.h" - -#include "fsfw/timemanager/Stopwatch.h" #include "fsfw/tasks/TaskFactory.h" - +#include "fsfw/timemanager/Stopwatch.h" #include "test/DummyParameter.h" -#include - -#include -#include -#include - -Q7STestTask::Q7STestTask(object_id_t objectId): TestTask(objectId) { +Q7STestTask::Q7STestTask(object_id_t objectId) : TestTask(objectId) { + doTestSdCard = false; + doTestScratchApi = false; + doTestGps = false; + doTestXadc = true; } ReturnValue_t Q7STestTask::performOneShotAction() { - //testSdCard(); - //testScratchApi(); - //testJsonLibDirect(); - //testDummyParams(); - //testProtHandler(); - FsOpCodes opCode = FsOpCodes::APPEND_TO_FILE; - testFileSystemHandlerDirect(opCode); - return TestTask::performOneShotAction(); + if (doTestSdCard) { + testSdCard(); + } + if (doTestScratchApi) { + testScratchApi(); + } + // testJsonLibDirect(); + // testDummyParams(); + // testProtHandler(); + FsOpCodes opCode = FsOpCodes::APPEND_TO_FILE; + testFileSystemHandlerDirect(opCode); + return TestTask::performOneShotAction(); +} + +ReturnValue_t Q7STestTask::performPeriodicAction() { + if (doTestGps) { + testGpsDaemon(); + } + if (doTestXadc) { + xadcTest(); + } + return TestTask::performPeriodicAction(); } void Q7STestTask::testSdCard() { - using namespace std; - Stopwatch stopwatch; - int result = std::system("q7hw sd info all > /tmp/sd_status.txt"); - if(result != 0) { - sif::debug << "system call failed with " << result << endl; + using namespace std; + Stopwatch stopwatch; + int result = std::system("q7hw sd info all > /tmp/sd_status.txt"); + if (result != 0) { + sif::debug << "system call failed with " << result << endl; + } + ifstream sdStatus("/tmp/sd_status.txt"); + string line; + uint8_t idx = 0; + while (std::getline(sdStatus, line)) { + std::istringstream iss(line); + string word; + while (iss >> word) { + if (word == "on") { + sif::info << "SD card " << static_cast(idx) << " is on" << endl; + } else if (word == "off") { + sif::info << "SD card " << static_cast(idx) << " is off" << endl; + } } - ifstream sdStatus("/tmp/sd_status.txt"); - string line; - uint8_t idx = 0; - while (std::getline(sdStatus, line)) { - std::istringstream iss(line); - string word; - while(iss >> word) { - if(word == "on") { - sif::info << "SD card " << static_cast(idx) << " is on" << endl; - } - else if(word == "off") { - sif::info << "SD card " << static_cast(idx) << " is off" << endl; - } - } - idx++; - } - std::remove("/tmp/sd_status.txt"); + idx++; + } + std::remove("/tmp/sd_status.txt"); } void Q7STestTask::fileTests() { - using namespace std; - ofstream testFile("/tmp/test.txt"); - testFile << "Hallo Welt" << endl; - testFile.close(); + using namespace std; + ofstream testFile("/tmp/test.txt"); + testFile << "Hallo Welt" << endl; + testFile.close(); - system("echo \"Hallo Welt\" > /tmp/test2.txt"); - system("echo \"Hallo Welt\""); + system("echo \"Hallo Welt\" > /tmp/test2.txt"); + system("echo \"Hallo Welt\""); } void Q7STestTask::testScratchApi() { - ReturnValue_t result = scratch::writeNumber("TEST", 1); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::debug << "Q7STestTask::scratchApiTest: Writing number failed" << std::endl; - } - int number = 0; - result = scratch::readNumber("TEST", number); - sif::info << "Q7STestTask::testScratchApi: Value for key \"TEST\": " << number << std::endl; - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::debug << "Q7STestTask::scratchApiTest: Reading number failed" << std::endl; - } + ReturnValue_t result = scratch::writeNumber("TEST", 1); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "Q7STestTask::scratchApiTest: Writing number failed" << std::endl; + } + int number = 0; + result = scratch::readNumber("TEST", number); + sif::info << "Q7STestTask::testScratchApi: Value for key \"TEST\": " << number << std::endl; + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "Q7STestTask::scratchApiTest: Reading number failed" << std::endl; + } - result = scratch::writeString("TEST2", "halloWelt"); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::debug << "Q7STestTask::scratchApiTest: Writing string failed" << std::endl; - } - std::string string; - result = scratch::readString("TEST2", string); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::debug << "Q7STestTask::scratchApiTest: Reading number failed" << std::endl; - } - sif::info << "Q7STestTask::testScratchApi: Value for key \"TEST2\": " << string << std::endl; + result = scratch::writeString("TEST2", "halloWelt"); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "Q7STestTask::scratchApiTest: Writing string failed" << std::endl; + } + std::string string; + result = scratch::readString("TEST2", string); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "Q7STestTask::scratchApiTest: Reading number failed" << std::endl; + } + sif::info << "Q7STestTask::testScratchApi: Value for key \"TEST2\": " << string << std::endl; - result = scratch::clearValue("TEST"); - result = scratch::clearValue("TEST2"); + result = scratch::clearValue("TEST"); + result = scratch::clearValue("TEST2"); } void Q7STestTask::testJsonLibDirect() { - Stopwatch stopwatch; - // for convenience - using json = nlohmann::json; - json helloTest; - // add a number that is stored as double (note the implicit conversion of j to an object) - helloTest["pi"] = 3.141; - std::string mntPrefix = SdCardManager::instance()->getCurrentMountPrefix(); - std::string fileName = mntPrefix + "/pretty.json"; - std::ofstream o(fileName); - o << std::setw(4) << helloTest << std::endl; + Stopwatch stopwatch; + // for convenience + using json = nlohmann::json; + json helloTest; + // add a number that is stored as double (note the implicit conversion of j to an object) + helloTest["pi"] = 3.141; + std::string mntPrefix = SdCardManager::instance()->getCurrentMountPrefix(); + std::string fileName = mntPrefix + "/pretty.json"; + std::ofstream o(fileName); + o << std::setw(4) << helloTest << std::endl; } void Q7STestTask::testDummyParams() { - std::string mntPrefix = SdCardManager::instance()->getCurrentMountPrefix(); - DummyParameter param(mntPrefix, "dummy_json.txt"); - param.printKeys(); - param.print(); - if(not param.getJsonFileExists()) { - param.writeJsonFile(); - } - - ReturnValue_t result = param.readJsonFile(); - if(result != HasReturnvaluesIF::RETURN_OK) { - - } - - param.setValue(DummyParameter::DUMMY_KEY_PARAM_1, 3); - param.setValue(DummyParameter::DUMMY_KEY_PARAM_2, "blirb"); - + std::string mntPrefix = SdCardManager::instance()->getCurrentMountPrefix(); + DummyParameter param(mntPrefix, "dummy_json.txt"); + param.printKeys(); + param.print(); + if (not param.getJsonFileExists()) { param.writeJsonFile(); - param.print(); + } - int test = 0; - result = param.getValue(DummyParameter::DUMMY_KEY_PARAM_1, &test); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1 - << " does not exist" << std::endl; - } - std::string test2; - result = param.getValue(DummyParameter::DUMMY_KEY_PARAM_2, &test2); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1 - << " does not exist" << std::endl; - } - sif::info << "Test value (3 expected): " << test << std::endl; - sif::info << "Test value 2 (\"blirb\" expected): " << test2 << std::endl; + ReturnValue_t result = param.readJsonFile(); + if (result != HasReturnvaluesIF::RETURN_OK) { + } + + param.setValue(DummyParameter::DUMMY_KEY_PARAM_1, 3); + param.setValue(DummyParameter::DUMMY_KEY_PARAM_2, "blirb"); + + param.writeJsonFile(); + param.print(); + + int test = 0; + result = param.getValue(DummyParameter::DUMMY_KEY_PARAM_1, test); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1 + << " does not exist" << std::endl; + } + std::string test2; + result = param.getValue(DummyParameter::DUMMY_KEY_PARAM_2, test2); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1 + << " does not exist" << std::endl; + } + sif::info << "Test value (3 expected): " << test << std::endl; + sif::info << "Test value 2 (\"blirb\" expected): " << test2 << std::endl; } ReturnValue_t Q7STestTask::initialize() { - coreController = ObjectManager::instance()->get(objects::CORE_CONTROLLER); - if(coreController == nullptr) { - sif::warning << "Q7STestTask::initialize: Could not retrieve CORE_CONTROLLER object" << - std::endl; - } - return TestTask::initialize(); + coreController = ObjectManager::instance()->get(objects::CORE_CONTROLLER); + if (coreController == nullptr) { + sif::warning << "Q7STestTask::initialize: Could not retrieve CORE_CONTROLLER object" + << std::endl; + } + return TestTask::initialize(); } void Q7STestTask::testProtHandler() { - bool opPerformed = false; - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - // If any chips are unlocked, lock them here - result = coreController->setBootCopyProtection( - CoreController::Chip::ALL_CHIP, CoreController::Copy::ALL_COPY, true, - opPerformed, true); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; - } + bool opPerformed = false; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + // If any chips are unlocked, lock them here + result = coreController->setBootCopyProtection(xsc::Chip::ALL_CHIP, xsc::Copy::ALL_COPY, true, + opPerformed, true); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; + } - // unlock own copy - result = coreController->setBootCopyProtection( - CoreController::Chip::SELF_CHIP, CoreController::Copy::SELF_COPY, false, - opPerformed, true); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; - } - if(not opPerformed) { - sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl; - } - int retval = std::system("print-chip-prot-status.sh"); - if(retval != 0) { - utility::handleSystemError(retval, "Q7STestTask::testProtHandler"); - } + // unlock own copy + result = coreController->setBootCopyProtection(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, false, + opPerformed, true); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; + } + if (not opPerformed) { + sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl; + } + int retval = std::system("print-chip-prot-status.sh"); + if (retval != 0) { + utility::handleSystemError(retval, "Q7STestTask::testProtHandler"); + } - // lock own copy - result = coreController->setBootCopyProtection( - CoreController::Chip::SELF_CHIP, CoreController::Copy::SELF_COPY, true, - opPerformed, true); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; - } - if(not opPerformed) { - sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl; - } - retval = std::system("print-chip-prot-status.sh"); - if(retval != 0) { - utility::handleSystemError(retval, "Q7STestTask::testProtHandler"); - } + // lock own copy + result = coreController->setBootCopyProtection(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, true, + opPerformed, true); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; + } + if (not opPerformed) { + sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl; + } + retval = std::system("print-chip-prot-status.sh"); + if (retval != 0) { + utility::handleSystemError(retval, "Q7STestTask::testProtHandler"); + } - // unlock specific copy - result = coreController->setBootCopyProtection( - CoreController::Chip::CHIP_1, CoreController::Copy::COPY_1, false, - opPerformed, true); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; - } - if(not opPerformed) { - sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl; - } - retval = std::system("print-chip-prot-status.sh"); - if(retval != 0) { - utility::handleSystemError(retval, "Q7STestTask::testProtHandler"); - } + // unlock specific copy + result = coreController->setBootCopyProtection(xsc::Chip::CHIP_1, xsc::Copy::COPY_1, false, + opPerformed, true); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; + } + if (not opPerformed) { + sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl; + } + retval = std::system("print-chip-prot-status.sh"); + if (retval != 0) { + utility::handleSystemError(retval, "Q7STestTask::testProtHandler"); + } - // lock specific copy - result = coreController->setBootCopyProtection( - CoreController::Chip::CHIP_1, CoreController::Copy::COPY_1, true, - opPerformed, true); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; - } - if(not opPerformed) { - sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl; - } - retval = std::system("print-chip-prot-status.sh"); - if(retval != 0) { - utility::handleSystemError(retval, "Q7STestTask::testProtHandler"); - } + // lock specific copy + result = coreController->setBootCopyProtection(xsc::Chip::CHIP_1, xsc::Copy::COPY_1, true, + opPerformed, true); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; + } + if (not opPerformed) { + sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl; + } + retval = std::system("print-chip-prot-status.sh"); + if (retval != 0) { + utility::handleSystemError(retval, "Q7STestTask::testProtHandler"); + } +} + +void Q7STestTask::testGpsDaemon() { + gpsmm gpsmm(GPSD_SHARED_MEMORY, 0); + gps_data_t* gps; + gps = gpsmm.read(); + if (gps == nullptr) { + sif::warning << "Q7STestTask: Reading GPS data failed" << std::endl; + } + sif::info << "-- Q7STestTask: GPS shared memory read test --" << std::endl; + time_t timeRaw = gps->fix.time.tv_sec; + std::tm* time = gmtime(&timeRaw); + sif::info << "Time: " << std::put_time(time, "%c %Z") << std::endl; + sif::info << "Visible satellites: " << gps->satellites_visible << std::endl; + sif::info << "Satellites used: " << gps->satellites_used << std::endl; + sif::info << "Fix (0:Not Seen|1:No Fix|2:2D|3:3D): " << gps->fix.mode << std::endl; + sif::info << "Latitude: " << gps->fix.latitude << std::endl; + sif::info << "Longitude: " << gps->fix.longitude << std::endl; + sif::info << "Altitude(MSL): " << gps->fix.altMSL << std::endl; + sif::info << "Speed(m/s): " << gps->fix.speed << std::endl; } void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) { - auto fsHandler = ObjectManager::instance()-> - get(objects::FILE_SYSTEM_HANDLER); - if(fsHandler == nullptr) { - sif::warning << "Q7STestTask::testFileSystemHandlerDirect: No FS handler running.." - << std::endl; - } - FileSystemHandler::FsCommandCfg cfg = {}; - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + auto fsHandler = ObjectManager::instance()->get(objects::FILE_SYSTEM_HANDLER); + if (fsHandler == nullptr) { + sif::warning << "Q7STestTask::testFileSystemHandlerDirect: No FS handler running.." + << std::endl; + } + FileSystemHandler::FsCommandCfg cfg = {}; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - // Lambda for common code - auto createNonEmptyTmpDir = [&]() { - if(not std::filesystem::exists("/tmp/test")) { - result = fsHandler->createDirectory("/tmp", "test", false, &cfg); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - } - // Creating sample files - sif::info << "Creating sample files in directory" << std::endl; - result = fsHandler->createFile("/tmp/test", "test1.txt", nullptr, 0, &cfg); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = fsHandler->createFile("/tmp/test", "test2.txt", nullptr, 0, &cfg); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + // Lambda for common code + auto createNonEmptyTmpDir = [&]() { + if (not std::filesystem::exists("/tmp/test")) { + result = fsHandler->createDirectory("/tmp", "test", false, &cfg); + if (result != HasReturnvaluesIF::RETURN_OK) { return result; - }; + } + } + // Creating sample files + sif::info << "Creating sample files in directory" << std::endl; + result = fsHandler->createFile("/tmp/test", "test1.txt", nullptr, 0, &cfg); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = fsHandler->createFile("/tmp/test", "test2.txt", nullptr, 0, &cfg); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return result; + }; - - switch(opCode) { - case(FsOpCodes::CREATE_EMPTY_FILE_IN_TMP): { - // No mount prefix, cause file is created in tmp - cfg.useMountPrefix = false; - sif::info << "Creating empty file in /tmp folder" << std::endl; - // Do not delete file, user can check existence in shell + switch (opCode) { + case (FsOpCodes::CREATE_EMPTY_FILE_IN_TMP): { + // No mount prefix, cause file is created in tmp + cfg.useMountPrefix = false; + sif::info << "Creating empty file in /tmp folder" << std::endl; + // Do not delete file, user can check existence in shell + fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg); + break; + } + case (FsOpCodes::REMOVE_TMP_FILE): { + sif::info << "Deleting /tmp/test.txt sample file" << std::endl; + // No mount prefix, cause file is created in tmp + cfg.useMountPrefix = false; + if (not std::filesystem::exists("/tmp/test.txt")) { + // Creating sample file + sif::info << "Creating sample file /tmp/test.txt to delete" << std::endl; fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg); - break; + } + result = fsHandler->removeFile("/tmp", "test.txt", &cfg); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "File removed successfully" << std::endl; + } else { + sif::warning << "File removal failed!" << std::endl; + } + break; } - case(FsOpCodes::REMOVE_TMP_FILE): { - sif::info << "Deleting /tmp/test.txt sample file" << std::endl; - // No mount prefix, cause file is created in tmp - cfg.useMountPrefix = false; - if(not std::filesystem::exists("/tmp/test.txt")) { - // Creating sample file - sif::info << "Creating sample file /tmp/test.txt to delete" << std::endl; - fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg); - } - result = fsHandler->removeFile("/tmp", "test.txt", &cfg); - if(result == HasReturnvaluesIF::RETURN_OK) { - sif::info << "File removed successfully" << std::endl; - } - else { - sif::warning << "File removal failed!" << std::endl; - } - break; + case (FsOpCodes::CREATE_DIR_IN_TMP): { + // No mount prefix, cause file is created in tmp + cfg.useMountPrefix = false; + sif::info << "Creating empty file in /tmp folder" << std::endl; + // Do not delete file, user can check existence in shell + ReturnValue_t result = fsHandler->createDirectory("/tmp/", "test", false, &cfg); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Directory created successfully" << std::endl; + } else { + sif::warning << "Directory creation failed!" << std::endl; + } + break; } - case(FsOpCodes::CREATE_DIR_IN_TMP): { - // No mount prefix, cause file is created in tmp - cfg.useMountPrefix = false; - sif::info << "Creating empty file in /tmp folder" << std::endl; - // Do not delete file, user can check existence in shell - ReturnValue_t result = fsHandler->createDirectory("/tmp/", "test", false, &cfg); - if(result == HasReturnvaluesIF::RETURN_OK) { - sif::info << "Directory created successfully" << std::endl; - } - else { - sif::warning << "Directory creation failed!" << std::endl; - } - break; + case (FsOpCodes::REMOVE_EMPTY_DIR_IN_TMP): { + // No mount prefix, cause file is created in tmp + cfg.useMountPrefix = false; + if (not std::filesystem::exists("/tmp/test")) { + result = fsHandler->createDirectory("/tmp", "test", false, &cfg); + } else { + // Delete any leftover files to regular dir removal works + std::remove("/tmp/test/*"); + } + result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Directory removed successfully" << std::endl; + } else { + sif::warning << "Directory removal failed!" << std::endl; + } + break; } - case(FsOpCodes::REMOVE_EMPTY_DIR_IN_TMP): { - // No mount prefix, cause file is created in tmp - cfg.useMountPrefix = false; - if(not std::filesystem::exists("/tmp/test")) { - result = fsHandler->createDirectory("/tmp", "test", false, &cfg); - } - else { - // Delete any leftover files to regular dir removal works - std::remove("/tmp/test/*"); - } - result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg); - if(result == HasReturnvaluesIF::RETURN_OK) { - sif::info << "Directory removed successfully" << std::endl; - } - else { - sif::warning << "Directory removal failed!" << std::endl; - } - break; + case (FsOpCodes::REMOVE_FILLED_DIR_IN_TMP): { + result = createNonEmptyTmpDir(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return; + } + result = fsHandler->removeDirectory("/tmp/", "test", true, &cfg); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Directory removed recursively successfully" << std::endl; + } else { + sif::warning << "Recursive directory removal failed!" << std::endl; + } + break; } - case(FsOpCodes::REMOVE_FILLED_DIR_IN_TMP): { - result = createNonEmptyTmpDir(); - if(result != HasReturnvaluesIF::RETURN_OK) { - return; - } - result = fsHandler->removeDirectory("/tmp/", "test", true, &cfg); - if(result == HasReturnvaluesIF::RETURN_OK) { - sif::info << "Directory removed recursively successfully" << std::endl; - } - else { - sif::warning << "Recursive directory removal failed!" << std::endl; - } - break; + case (FsOpCodes::ATTEMPT_DIR_REMOVAL_NON_EMPTY): { + result = createNonEmptyTmpDir(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return; + } + result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::info << "Directory removal attempt failed as expected" << std::endl; + } else { + sif::warning << "Directory removal worked when it should not have!" << std::endl; + } + break; } - case(FsOpCodes::ATTEMPT_DIR_REMOVAL_NON_EMPTY): { - result = createNonEmptyTmpDir(); - if(result != HasReturnvaluesIF::RETURN_OK) { - return; - } - result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::info << "Directory removal attempt failed as expected" << std::endl; - } - else { - sif::warning << "Directory removal worked when it should not have!" << std::endl; - } - break; - } - case(FsOpCodes::RENAME_FILE): { - // No mount prefix, cause file is created in tmp - cfg.useMountPrefix = false; - if(std::filesystem::exists("/tmp/test.txt")) { - fsHandler->removeDirectory("/tmp/", "test", false, &cfg); - } - sif::info << "Creating empty file /tmp/test.txt and rename to /tmp/test2.txt" << std::endl; - // Do not delete file, user can check existence in shell - fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg); - fsHandler->renameFile("/tmp/", "test.txt", "test2.txt", &cfg); - break; - } - case(FsOpCodes::APPEND_TO_FILE): { - // No mount prefix, cause file is created in tmp - cfg.useMountPrefix = false; - if(std::filesystem::exists("/tmp/test.txt")) { - fsHandler->removeDirectory("/tmp/", "test", false, &cfg); - } - if(std::filesystem::exists("/tmp/test.txt")) { - fsHandler->removeDirectory("/tmp/", "test", false, &cfg); - } - sif::info << "Creating empty file /tmp/test.txt and adding content" << std::endl; - std::string content = "Hello World\n"; - // Do not delete file, user can check existence in shell - fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg); - fsHandler->appendToFile("/tmp/", "test.txt", reinterpret_cast( - content.data()), content.size(), 0, &cfg); + case (FsOpCodes::RENAME_FILE): { + // No mount prefix, cause file is created in tmp + cfg.useMountPrefix = false; + if (std::filesystem::exists("/tmp/test.txt")) { + fsHandler->removeDirectory("/tmp/", "test", false, &cfg); + } + sif::info << "Creating empty file /tmp/test.txt and rename to /tmp/test2.txt" << std::endl; + // Do not delete file, user can check existence in shell + fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg); + fsHandler->renameFile("/tmp/", "test.txt", "test2.txt", &cfg); + break; } + case (FsOpCodes::APPEND_TO_FILE): { + // No mount prefix, cause file is created in tmp + cfg.useMountPrefix = false; + if (std::filesystem::exists("/tmp/test.txt")) { + fsHandler->removeDirectory("/tmp/", "test", false, &cfg); + } + if (std::filesystem::exists("/tmp/test.txt")) { + fsHandler->removeDirectory("/tmp/", "test", false, &cfg); + } + sif::info << "Creating empty file /tmp/test.txt and adding content" << std::endl; + std::string content = "Hello World\n"; + // Do not delete file, user can check existence in shell + fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg); + fsHandler->appendToFile("/tmp/", "test.txt", reinterpret_cast(content.data()), + content.size(), 0, &cfg); } + } +} + +void Q7STestTask::xadcTest() { + ReturnValue_t result = RETURN_OK; + float temperature = 0; + float vccPint = 0; + float vccPaux = 0; + float vccInt = 0; + float vccAux = 0; + float vccBram = 0; + float vccOddr = 0; + float vrefp = 0; + float vrefn = 0; + Xadc xadc; + result = xadc.getTemperature(temperature); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Q7STestTask::xadcTest: Chip Temperature: " << temperature << " °C" << std::endl; + } + result = xadc.getVccPint(vccPint); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Q7STestTask::xadcTest: VCC PS internal: " << vccPint << " mV" << std::endl; + } + result = xadc.getVccPaux(vccPaux); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Q7STestTask::xadcTest: VCC PS auxilliary: " << vccPaux << " mV" << std::endl; + } + result = xadc.getVccInt(vccInt); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Q7STestTask::xadcTest: VCC PL internal: " << vccInt << " mV" << std::endl; + } + result = xadc.getVccAux(vccAux); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Q7STestTask::xadcTest: VCC PL auxilliary: " << vccAux << " mV" << std::endl; + } + result = xadc.getVccBram(vccBram); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Q7STestTask::xadcTest: VCC BRAM: " << vccBram << " mV" << std::endl; + } + result = xadc.getVccOddr(vccOddr); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Q7STestTask::xadcTest: VCC PS I/O DDR : " << vccOddr << " mV" << std::endl; + } + result = xadc.getVrefp(vrefp); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Q7STestTask::xadcTest: Vrefp : " << vrefp << " mV" << std::endl; + } + result = xadc.getVrefn(vrefn); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "Q7STestTask::xadcTest: Vrefn : " << vrefn << " mV" << std::endl; + } } diff --git a/bsp_q7s/boardtest/Q7STestTask.h b/bsp_q7s/boardtest/Q7STestTask.h index 5e11b374..ebef1fad 100644 --- a/bsp_q7s/boardtest/Q7STestTask.h +++ b/bsp_q7s/boardtest/Q7STestTask.h @@ -3,35 +3,46 @@ #include "test/testtasks/TestTask.h" -class Q7STestTask: public TestTask { -public: - Q7STestTask(object_id_t objectId); +class CoreController; - ReturnValue_t initialize() override; -private: - CoreController* coreController = nullptr; - ReturnValue_t performOneShotAction() override; +class Q7STestTask : public TestTask { + public: + Q7STestTask(object_id_t objectId); - void testSdCard(); - void fileTests(); + ReturnValue_t initialize() override; - void testScratchApi(); - void testJsonLibDirect(); - void testDummyParams(); - void testProtHandler(); + private: + bool doTestSdCard = false; + bool doTestScratchApi = false; + bool doTestGps = false; + bool doTestXadc = false; - enum FsOpCodes { - CREATE_EMPTY_FILE_IN_TMP, - REMOVE_TMP_FILE, - CREATE_DIR_IN_TMP, - REMOVE_EMPTY_DIR_IN_TMP, - ATTEMPT_DIR_REMOVAL_NON_EMPTY, - REMOVE_FILLED_DIR_IN_TMP, - RENAME_FILE, - APPEND_TO_FILE, - }; - void testFileSystemHandlerDirect(FsOpCodes opCode); + CoreController* coreController = nullptr; + ReturnValue_t performOneShotAction() override; + ReturnValue_t performPeriodicAction() override; + + void testGpsDaemon(); + + void testSdCard(); + void fileTests(); + void xadcTest(); + + void testScratchApi(); + void testJsonLibDirect(); + void testDummyParams(); + void testProtHandler(); + + enum FsOpCodes { + CREATE_EMPTY_FILE_IN_TMP, + REMOVE_TMP_FILE, + CREATE_DIR_IN_TMP, + REMOVE_EMPTY_DIR_IN_TMP, + ATTEMPT_DIR_REMOVAL_NON_EMPTY, + REMOVE_FILLED_DIR_IN_TMP, + RENAME_FILE, + APPEND_TO_FILE, + }; + void testFileSystemHandlerDirect(FsOpCodes opCode); }; - #endif /* BSP_Q7S_BOARDTEST_Q7STESTTASK_H_ */ diff --git a/bsp_q7s/callbacks/CMakeLists.txt b/bsp_q7s/callbacks/CMakeLists.txt index 8c83e26f..a4462937 100644 --- a/bsp_q7s/callbacks/CMakeLists.txt +++ b/bsp_q7s/callbacks/CMakeLists.txt @@ -1,4 +1,6 @@ -target_sources(${TARGET_NAME} PRIVATE +target_sources(${OBSW_NAME} PRIVATE rwSpiCallback.cpp gnssCallback.cpp + pcduSwitchCb.cpp + gpioCallbacks.cpp ) diff --git a/bsp_q7s/callbacks/gnssCallback.cpp b/bsp_q7s/callbacks/gnssCallback.cpp index 479f4a2b..d5dbc3b0 100644 --- a/bsp_q7s/callbacks/gnssCallback.cpp +++ b/bsp_q7s/callbacks/gnssCallback.cpp @@ -1,26 +1,25 @@ #include "gnssCallback.h" -#include "devices/gpioIds.h" +#include "devices/gpioIds.h" #include "fsfw/tasks/TaskFactory.h" -ReturnValue_t gps::triggerGpioResetPin(void *args) { - ResetArgs* resetArgs = reinterpret_cast(args); - if(args == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; - } - if (resetArgs->gpioComIF == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; - } - gpioId_t gpioId; - if(resetArgs->gnss1) { - gpioId = gpioIds::GNSS_1_NRESET; +ReturnValue_t gps::triggerGpioResetPin(void* args) { + ResetArgs* resetArgs = reinterpret_cast(args); + if (args == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + if (resetArgs->gpioComIF == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + gpioId_t gpioId; + if (resetArgs->gnss1) { + gpioId = gpioIds::GNSS_1_NRESET; - } - else { - gpioId = gpioIds::GNSS_0_NRESET; - } - resetArgs->gpioComIF->pullLow(gpioId); - TaskFactory::delayTask(resetArgs->waitPeriodMs); - resetArgs->gpioComIF->pullHigh(gpioId); - return HasReturnvaluesIF::RETURN_OK; + } else { + gpioId = gpioIds::GNSS_0_NRESET; + } + resetArgs->gpioComIF->pullLow(gpioId); + TaskFactory::delayTask(resetArgs->waitPeriodMs); + resetArgs->gpioComIF->pullHigh(gpioId); + return HasReturnvaluesIF::RETURN_OK; } diff --git a/bsp_q7s/callbacks/gnssCallback.h b/bsp_q7s/callbacks/gnssCallback.h index 9cbb6669..3e769899 100644 --- a/bsp_q7s/callbacks/gnssCallback.h +++ b/bsp_q7s/callbacks/gnssCallback.h @@ -1,13 +1,13 @@ #ifndef BSP_Q7S_CALLBACKS_GNSSCALLBACK_H_ #define BSP_Q7S_CALLBACKS_GNSSCALLBACK_H_ -#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" struct ResetArgs { - bool gnss1 = false; - LinuxLibgpioIF* gpioComIF = nullptr; - uint32_t waitPeriodMs = 100; + bool gnss1 = false; + LinuxLibgpioIF* gpioComIF = nullptr; + uint32_t waitPeriodMs = 100; }; namespace gps { diff --git a/bsp_q7s/callbacks/gpioCallbacks.cpp b/bsp_q7s/callbacks/gpioCallbacks.cpp new file mode 100644 index 00000000..e5fd877a --- /dev/null +++ b/bsp_q7s/callbacks/gpioCallbacks.cpp @@ -0,0 +1,487 @@ +#include "gpioCallbacks.h" + +#include +#include +#include +#include + +#include "busConf.h" + +namespace gpioCallbacks { + +GpioIF* gpioComInterface; + +void initSpiCsDecoder(GpioIF* gpioComIF) { + using namespace gpio; + ReturnValue_t result; + + if (gpioComIF == nullptr) { + sif::debug << "initSpiCsDecoder: Invalid gpioComIF" << std::endl; + return; + } + + gpioComInterface = gpioComIF; + + GpioCookie* spiMuxGpios = new GpioCookie; + + GpiodRegularByLineName* spiMuxBit = nullptr; + /** Setting mux bit 1 to low will disable IC21 on the interface board */ + spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_0_PIN, "SPI Mux Bit 1", + Direction::OUT, Levels::HIGH); + spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_0, spiMuxBit); + /** Setting mux bit 2 to low disables IC1 on the TCS board */ + spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_1_PIN, "SPI Mux Bit 2", + Direction::OUT, Levels::HIGH); + spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit); + /** Setting mux bit 3 to low disables IC2 on the TCS board and IC22 on the interface board */ + spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_2_PIN, "SPI Mux Bit 3", + Direction::OUT, Levels::LOW); + spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit); + + /** The following gpios can take arbitrary initial values */ + spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_3_PIN, "SPI Mux Bit 4", + Direction::OUT, Levels::LOW); + spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit); + spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_4_PIN, "SPI Mux Bit 5", + Direction::OUT, Levels::LOW); + spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_4, spiMuxBit); + spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_5_PIN, "SPI Mux Bit 6", + Direction::OUT, Levels::LOW); + spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_5, spiMuxBit); + GpiodRegularByLineName* enRwDecoder = new GpiodRegularByLineName( + q7s::gpioNames::EN_RW_CS, "EN_RW_CS", Direction::OUT, Levels::HIGH); + spiMuxGpios->addGpio(gpioIds::EN_RW_CS, enRwDecoder); + + result = gpioComInterface->addGpios(spiMuxGpios); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "initSpiCsDecoder: Failed to add mux bit gpios to gpioComIF" << std::endl; + return; + } +} + +void spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, gpio::Levels value, + void* args) { + using namespace gpio; + if (gpioComInterface == nullptr) { + sif::debug << "spiCsDecoderCallback: No gpioComIF specified. Call initSpiCsDecoder " + << "to specify gpioComIF" << std::endl; + return; + } + + /* Reading is not supported by the callback function */ + if (gpioOp == gpio::GpioOperation::READ) { + return; + } + + if (value == Levels::HIGH) { + switch (gpioId) { + case (gpioIds::RTD_IC_3): { + disableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_4): { + disableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_5): { + disableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_6): { + disableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_7): { + disableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_8): { + disableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_9): { + disableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_10): { + disableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_11): { + disableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_12): { + disableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_13): { + disableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_14): { + disableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_15): { + disableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_16): { + disableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_17): { + disableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_18): { + disableDecoderTcsIc2(); + break; + } + case (gpioIds::CS_SUS_0): { + disableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_1): { + disableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_2): { + disableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_3): { + disableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_4): { + disableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_5): { + disableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_6): { + disableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_SUS_7): { + disableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_SUS_8): { + disableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_SUS_9): { + disableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_SUS_10): { + disableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_SUS_11): { + disableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_RW1): { + disableRwDecoder(); + break; + } + case (gpioIds::CS_RW2): { + disableRwDecoder(); + break; + } + case (gpioIds::CS_RW3): { + disableRwDecoder(); + break; + } + case (gpioIds::CS_RW4): { + disableRwDecoder(); + break; + } + default: + sif::debug << "spiCsDecoderCallback: Invalid gpio id " << gpioId << std::endl; + } + } else if (value == Levels::LOW) { + switch (gpioId) { + case (gpioIds::RTD_IC_3): { + selectY7(); + enableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_4): { + selectY6(); + enableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_5): { + selectY5(); + enableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_6): { + selectY4(); + enableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_7): { + selectY3(); + enableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_8): { + selectY2(); + enableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_9): { + selectY1(); + enableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_10): { + selectY0(); + enableDecoderTcsIc1(); + break; + } + case (gpioIds::RTD_IC_11): { + selectY7(); + enableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_12): { + selectY6(); + enableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_13): { + selectY5(); + enableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_14): { + selectY4(); + enableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_15): { + selectY3(); + enableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_16): { + selectY2(); + enableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_17): { + selectY1(); + enableDecoderTcsIc2(); + break; + } + case (gpioIds::RTD_IC_18): { + selectY0(); + enableDecoderTcsIc2(); + break; + } + case (gpioIds::CS_SUS_0): { + selectY0(); + enableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_1): { + selectY1(); + enableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_2): { + selectY2(); + enableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_3): { + selectY3(); + enableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_4): { + selectY4(); + enableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_5): { + selectY5(); + enableDecoderInterfaceBoardIc1(); + break; + } + case (gpioIds::CS_SUS_6): { + selectY0(); + enableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_SUS_7): { + selectY1(); + enableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_SUS_8): { + selectY2(); + enableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_SUS_9): { + selectY3(); + enableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_SUS_10): { + selectY4(); + enableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_SUS_11): { + selectY5(); + enableDecoderInterfaceBoardIc2(); + break; + } + case (gpioIds::CS_RW1): { + selectY0(); + enableRwDecoder(); + break; + } + case (gpioIds::CS_RW2): { + selectY1(); + enableRwDecoder(); + break; + } + case (gpioIds::CS_RW3): { + selectY2(); + enableRwDecoder(); + break; + } + case (gpioIds::CS_RW4): { + selectY3(); + enableRwDecoder(); + break; + } + default: + sif::debug << "spiCsDecoderCallback: Invalid gpio id " << gpioId << std::endl; + } + } else { + sif::debug << "spiCsDecoderCallback: Invalid value. Must be 0 or 1" << std::endl; + } +} + +void enableDecoderTcsIc1() { + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_0); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2); +} + +void enableDecoderTcsIc2() { + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_0); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); +} + +void enableDecoderInterfaceBoardIc1() { + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_0); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2); +} + +void enableDecoderInterfaceBoardIc2() { + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_0); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2); +} + +void disableDecoderTcsIc1() { + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_0); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2); +} + +void disableDecoderTcsIc2() { + // DO NOT CHANGE THE ORDER HERE + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_0); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); +} + +void disableDecoderInterfaceBoardIc1() { + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_0); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2); +} + +void disableDecoderInterfaceBoardIc2() { + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_0); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2); +} + +void enableRwDecoder() { gpioComInterface->pullHigh(gpioIds::EN_RW_CS); } + +void disableRwDecoder() { gpioComInterface->pullLow(gpioIds::EN_RW_CS); } + +void selectY0() { + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5); +} + +void selectY1() { + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5); +} + +void selectY2() { + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5); +} + +void selectY3() { + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5); +} + +void selectY4() { + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5); +} + +void selectY5() { + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5); +} + +void selectY6() { + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5); +} + +void selectY7() { + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4); + gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5); +} + +void disableAllDecoder() { + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_0); + gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1); + gpioComInterface->pullLow(gpioIds::EN_RW_CS); +} + +} // namespace gpioCallbacks diff --git a/bsp_q7s/callbacks/gpioCallbacks.h b/bsp_q7s/callbacks/gpioCallbacks.h new file mode 100644 index 00000000..6b4e99bf --- /dev/null +++ b/bsp_q7s/callbacks/gpioCallbacks.h @@ -0,0 +1,73 @@ +#ifndef LINUX_GPIO_GPIOCALLBACKS_H_ +#define LINUX_GPIO_GPIOCALLBACKS_H_ + +#include +#include + +namespace gpioCallbacks { + +/** + * @brief This function initializes the GPIOs used to control the SN74LVC138APWR decoders on + * the TCS Board and the interface board. + */ +void initSpiCsDecoder(GpioIF* gpioComIF); + +/** + * @brief This function implements the decoding to multiply gpios by using the decoder + * chips SN74LVC138APWR on the TCS board and the interface board. + */ +void spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, gpio::Levels value, + void* args); + +/** + * @brief This function sets mux bits 1-3 to a state which will only enable the decoder + * on the TCS board which is named to IC1 in the schematic. + */ +void enableDecoderTcsIc1(); + +/** + * @brief This function sets mux bits 1-3 to a state which will only enable the decoder + * on the TCS board which is named to IC2 in the schematic. + */ +void enableDecoderTcsIc2(); + +/** + * @brief This function sets mux bits 1-3 to a state which will only enable the decoder + * on the inteface board board which is named to IC21 in the schematic. + */ +void enableDecoderInterfaceBoardIc1(); + +/** + * @brief This function sets mux bits 1-3 to a state which will only enable the decoder + * on the inteface board board which is named to IC22 in the schematic. + */ +void enableDecoderInterfaceBoardIc2(); + +void disableDecoderTcsIc1(); +void disableDecoderTcsIc2(); +void disableDecoderInterfaceBoardIc1(); +void disableDecoderInterfaceBoardIc2(); + +/** + * @brief Enables the reaction wheel chip select decoder (IC3). + */ +void enableRwDecoder(); +void disableRwDecoder(); + +/** + * @brief This function disables all decoder. + */ +void disableAllDecoder(); + +/** The following functions enable the appropriate channel of the currently enabled decoder */ +void selectY0(); +void selectY1(); +void selectY2(); +void selectY3(); +void selectY4(); +void selectY5(); +void selectY6(); +void selectY7(); +} // namespace gpioCallbacks + +#endif /* LINUX_GPIO_GPIOCALLBACKS_H_ */ diff --git a/bsp_q7s/callbacks/pcduSwitchCb.cpp b/bsp_q7s/callbacks/pcduSwitchCb.cpp new file mode 100644 index 00000000..ec5f4dc5 --- /dev/null +++ b/bsp_q7s/callbacks/pcduSwitchCb.cpp @@ -0,0 +1,32 @@ +#include "pcduSwitchCb.h" + +#include + +#include "devices/gpioIds.h" + +void pcdu::switchCallback(GOMSPACE::Pdu pdu, uint8_t channel, bool state, void* args) { + LinuxLibgpioIF* gpioComIF = reinterpret_cast(args); + if (gpioComIF == nullptr) { + return; + } + if (pdu == GOMSPACE::Pdu::PDU1) { + PDU1::SwitchChannels typedChannel = static_cast(channel); + if (typedChannel == PDU1::SwitchChannels::ACS_A_SIDE) { + if (state) { + gpioComIF->pullHigh(gpioIds::GNSS_0_NRESET); + } else { + gpioComIF->pullLow(gpioIds::GNSS_0_NRESET); + } + } + + } else if (pdu == GOMSPACE::Pdu::PDU2) { + PDU2::SwitchChannels typedChannel = static_cast(channel); + if (typedChannel == PDU2::SwitchChannels::ACS_B_SIDE) { + if (state) { + gpioComIF->pullHigh(gpioIds::GNSS_1_NRESET); + } else { + gpioComIF->pullLow(gpioIds::GNSS_1_NRESET); + } + } + } +} diff --git a/bsp_q7s/callbacks/pcduSwitchCb.h b/bsp_q7s/callbacks/pcduSwitchCb.h new file mode 100644 index 00000000..d0f2b748 --- /dev/null +++ b/bsp_q7s/callbacks/pcduSwitchCb.h @@ -0,0 +1,14 @@ +#ifndef BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_ +#define BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_ + +#include + +#include "mission/devices/devicedefinitions/GomspaceDefinitions.h" + +namespace pcdu { + +void switchCallback(GOMSPACE::Pdu pdu, uint8_t channel, bool state, void* args); + +} + +#endif /* BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_ */ diff --git a/bsp_q7s/callbacks/rwSpiCallback.cpp b/bsp_q7s/callbacks/rwSpiCallback.cpp index 701fc8dc..3ca3c181 100644 --- a/bsp_q7s/callbacks/rwSpiCallback.cpp +++ b/bsp_q7s/callbacks/rwSpiCallback.cpp @@ -1,237 +1,232 @@ #include "rwSpiCallback.h" -#include "devices/gpioIds.h" -#include "mission/devices/RwHandler.h" -#include "fsfw_hal/linux/spi/SpiCookie.h" -#include "fsfw_hal/linux/UnixFileGuard.h" +#include "devices/gpioIds.h" #include "fsfw/serviceinterface/ServiceInterface.h" +#include "fsfw_hal/linux/UnixFileGuard.h" +#include "fsfw_hal/linux/spi/SpiCookie.h" +#include "mission/devices/RwHandler.h" namespace rwSpiCallback { -ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sendData, - size_t sendLen, void* args) { +ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sendData, + size_t sendLen, void* args) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + RwHandler* handler = reinterpret_cast(args); + if (handler == nullptr) { + sif::error << "rwSpiCallback::spiCallback: Pointer to handler is invalid" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } - RwHandler* handler = reinterpret_cast(args); - if(handler == nullptr) { - sif::error << "rwSpiCallback::spiCallback: Pointer to handler is invalid" - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; + uint8_t writeBuffer[2]; + uint8_t writeSize = 0; + + gpioId_t gpioId = cookie->getChipSelectPin(); + GpioIF* gpioIF = comIf->getGpioInterface(); + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + uint32_t timeoutMs = 0; + MutexIF* mutex = comIf->getMutex(&timeoutType, &timeoutMs); + if (mutex == nullptr or gpioIF == nullptr) { + sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + int fileDescriptor = 0; + std::string device = cookie->getSpiDevice(); + UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "rwSpiCallback::spiCallback"); + if (fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + sif::error << "rwSpiCallback::spiCallback: Failed to open device file" << std::endl; + return SpiComIF::OPENING_FILE_FAILED; + } + spi::SpiModes spiMode = spi::SpiModes::MODE_0; + uint32_t spiSpeed = 0; + cookie->getSpiParameters(spiMode, spiSpeed, nullptr); + comIf->setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); + + result = mutex->lockMutex(timeoutType, timeoutMs); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "rwSpiCallback::spiCallback: Failed to lock mutex" << std::endl; + return result; + } + + /** Sending frame start sign */ + writeBuffer[0] = 0x7E; + writeSize = 1; + + // Pull SPI CS low. For now, no support for active high given + if (gpioId != gpio::NO_GPIO) { + if (gpioIF->pullLow(gpioId) != HasReturnvaluesIF::RETURN_OK) { + sif::error << "rwSpiCallback::spiCallback: Failed to pull chip select low" << std::endl; } + } - uint8_t writeBuffer[2]; - uint8_t writeSize = 0; + if (write(fileDescriptor, writeBuffer, writeSize) != static_cast(writeSize)) { + sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl; + closeSpi(gpioId, gpioIF, mutex); + return RwHandler::SPI_WRITE_FAILURE; + } - gpioId_t gpioId = cookie->getChipSelectPin(); - GpioIF* gpioIF = comIf->getGpioInterface(); - MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; - uint32_t timeoutMs = 0; - MutexIF* mutex = comIf->getMutex(&timeoutType, &timeoutMs); - if(mutex == nullptr or gpioIF == nullptr) { - sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - - int fileDescriptor = 0; - std::string device = cookie->getSpiDevice(); - UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "rwSpiCallback::spiCallback"); - if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { - sif::error << "rwSpiCallback::spiCallback: Failed to open device file" << std::endl; - return SpiComIF::OPENING_FILE_FAILED; + /** Encoding and sending command */ + size_t idx = 0; + while (idx < sendLen) { + switch (*(sendData + idx)) { + case 0x7E: + writeBuffer[0] = 0x7D; + writeBuffer[1] = 0x5E; + writeSize = 2; + break; + case 0x7D: + writeBuffer[0] = 0x7D; + writeBuffer[1] = 0x5D; + writeSize = 2; + break; + default: + writeBuffer[0] = *(sendData + idx); + writeSize = 1; + break; } - spi::SpiModes spiMode = spi::SpiModes::MODE_0; - uint32_t spiSpeed = 0; - cookie->getSpiParameters(spiMode, spiSpeed, nullptr); - comIf->setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); - - result = mutex->lockMutex(timeoutType, timeoutMs); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::debug << "rwSpiCallback::spiCallback: Failed to lock mutex" << std::endl; - return result; - } - - /** Sending frame start sign */ - writeBuffer[0] = 0x7E; - writeSize = 1; - - // Pull SPI CS low. For now, no support for active high given - if(gpioId != gpio::NO_GPIO) { - if(gpioIF->pullLow(gpioId) != HasReturnvaluesIF::RETURN_OK) { - sif::error << "rwSpiCallback::spiCallback: Failed to pull chip select low" << std::endl; - } - } - if (write(fileDescriptor, writeBuffer, writeSize) != static_cast(writeSize)) { - sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl; + sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl; + closeSpi(gpioId, gpioIF, mutex); + return RwHandler::SPI_WRITE_FAILURE; + } + idx++; + } + + /** Sending frame end sign */ + writeBuffer[0] = 0x7E; + writeSize = 1; + + if (write(fileDescriptor, writeBuffer, writeSize) != static_cast(writeSize)) { + sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl; + closeSpi(gpioId, gpioIF, mutex); + return RwHandler::SPI_WRITE_FAILURE; + } + + uint8_t* rxBuf = nullptr; + result = comIf->getReadBuffer(cookie->getSpiAddress(), &rxBuf); + if (result != HasReturnvaluesIF::RETURN_OK) { + closeSpi(gpioId, gpioIF, mutex); + return result; + } + + size_t replyBufferSize = cookie->getMaxBufferSize(); + + /** There must be a delay of at least 20 ms after sending the command */ + usleep(RwDefinitions::SPI_REPLY_DELAY); + + /** + * The reaction wheel responds with empty frames while preparing the reply data. + * However, receiving more than 5 empty frames will be interpreted as an error. + */ + uint8_t byteRead = 0; + for (int idx = 0; idx < 10; idx++) { + if (read(fileDescriptor, &byteRead, 1) != 1) { + sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl; + closeSpi(gpioId, gpioIF, mutex); + return RwHandler::SPI_READ_FAILURE; + } + if (idx == 0) { + if (byteRead != FLAG_BYTE) { + sif::error << "Invalid data, expected start marker" << std::endl; closeSpi(gpioId, gpioIF, mutex); - return RwHandler::SPI_WRITE_FAILURE; + return RwHandler::NO_START_MARKER; + } } - /** Encoding and sending command */ - size_t idx = 0; - while(idx < sendLen) { - switch(*(sendData + idx)) { - case 0x7E: - writeBuffer[0] = 0x7D; - writeBuffer[1] = 0x5E; - writeSize = 2; - break; - case 0x7D: - writeBuffer[0] = 0x7D; - writeBuffer[1] = 0x5D; - writeSize = 2; - break; - default: - writeBuffer[0] = *(sendData + idx); - writeSize = 1; - break; - } - if (write(fileDescriptor, writeBuffer, writeSize) != static_cast(writeSize)) { - sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl; - closeSpi(gpioId, gpioIF, mutex); - return RwHandler::SPI_WRITE_FAILURE; - } - idx++; + if (byteRead != FLAG_BYTE) { + break; } - /** Sending frame end sign */ - writeBuffer[0] = 0x7E; - writeSize = 1; - - if (write(fileDescriptor, writeBuffer, writeSize) != static_cast(writeSize)) { - sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl; - closeSpi(gpioId, gpioIF, mutex); - return RwHandler::SPI_WRITE_FAILURE; - } - - uint8_t* rxBuf = nullptr; - result = comIf->getReadBuffer(cookie->getSpiAddress(), &rxBuf); - if(result != HasReturnvaluesIF::RETURN_OK) { - closeSpi(gpioId, gpioIF, mutex); - return result; - } - - size_t replyBufferSize = cookie->getMaxBufferSize(); - - /** There must be a delay of at least 20 ms after sending the command */ - usleep(RwDefinitions::SPI_REPLY_DELAY); - - /** - * The reaction wheel responds with empty frames while preparing the reply data. - * However, receiving more than 5 empty frames will be interpreted as an error. - */ - uint8_t byteRead = 0; - for (int idx = 0; idx < 10; idx++) { - if(read(fileDescriptor, &byteRead, 1) != 1) { - sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl; - closeSpi(gpioId, gpioIF, mutex); - return RwHandler::SPI_READ_FAILURE; - } - if(idx == 0) { - if(byteRead != FLAG_BYTE) { - sif::error << "Invalid data, expected start marker" << std::endl; - closeSpi(gpioId, gpioIF, mutex); - return RwHandler::NO_START_MARKER; - } - } - - if (byteRead != FLAG_BYTE) { - break; - } - - if (idx == 9) { - sif::error << "rwSpiCallback::spiCallback: Empty frame timeout" << std::endl; - closeSpi(gpioId, gpioIF, mutex); - return RwHandler::NO_REPLY; - } + if (idx == 9) { + sif::error << "rwSpiCallback::spiCallback: Empty frame timeout" << std::endl; + closeSpi(gpioId, gpioIF, mutex); + return RwHandler::NO_REPLY; } + } #if FSFW_HAL_SPI_WIRETAPPING == 1 - sif::info << "RW start marker detected" << std::endl; + sif::info << "RW start marker detected" << std::endl; #endif - size_t decodedFrameLen = 0; - while(decodedFrameLen < replyBufferSize) { - - /** First byte already read in */ - if (decodedFrameLen != 0) { - byteRead = 0; - if(read(fileDescriptor, &byteRead, 1) != 1) { - sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl; - result = RwHandler::SPI_READ_FAILURE; - break; - } - } - - if (byteRead == FLAG_BYTE) { - /** Reached end of frame */ - break; - } - else if (byteRead == 0x7D) { - if(read(fileDescriptor, &byteRead, 1) != 1) { - sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl; - result = RwHandler::SPI_READ_FAILURE; - break; - } - if (byteRead == 0x5E) { - *(rxBuf + decodedFrameLen) = 0x7E; - decodedFrameLen++; - continue; - } - else if (byteRead == 0x5D) { - *(rxBuf + decodedFrameLen) = 0x7D; - decodedFrameLen++; - continue; - } - else { - sif::error << "rwSpiCallback::spiCallback: Invalid substitute" << std::endl; - closeSpi(gpioId, gpioIF, mutex); - result = RwHandler::INVALID_SUBSTITUTE; - break; - } - } - else { - *(rxBuf + decodedFrameLen) = byteRead; - decodedFrameLen++; - } - - /** - * There might be the unlikely case that each byte in a get-telemetry reply has been - * replaced by its substitute. Than the next byte must correspond to the end sign 0x7E. - * Otherwise there might be something wrong. - */ - if (decodedFrameLen == replyBufferSize) { - if(read(fileDescriptor, &byteRead, 1) != 1) { - sif::error << "rwSpiCallback::spiCallback: Failed to read last byte" << std::endl; - result = RwHandler::SPI_READ_FAILURE; - break; - } - if (byteRead != 0x7E) { - sif::error << "rwSpiCallback::spiCallback: Missing end sign 0x7E" << std::endl; - decodedFrameLen--; - result = RwHandler::MISSING_END_SIGN; - break; - } - } - result = HasReturnvaluesIF::RETURN_OK; + size_t decodedFrameLen = 0; + while (decodedFrameLen < replyBufferSize) { + /** First byte already read in */ + if (decodedFrameLen != 0) { + byteRead = 0; + if (read(fileDescriptor, &byteRead, 1) != 1) { + sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl; + result = RwHandler::SPI_READ_FAILURE; + break; + } } - cookie->setTransferSize(decodedFrameLen); - - closeSpi(gpioId, gpioIF, mutex); - - return result; -} - -void closeSpi (gpioId_t gpioId, GpioIF* gpioIF, MutexIF* mutex) { - if(gpioId != gpio::NO_GPIO) { - if (gpioIF->pullHigh(gpioId) != HasReturnvaluesIF::RETURN_OK) { - sif::error << "closeSpi: Failed to pull chip select high" << std::endl; - } + if (byteRead == FLAG_BYTE) { + /** Reached end of frame */ + break; + } else if (byteRead == 0x7D) { + if (read(fileDescriptor, &byteRead, 1) != 1) { + sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl; + result = RwHandler::SPI_READ_FAILURE; + break; + } + if (byteRead == 0x5E) { + *(rxBuf + decodedFrameLen) = 0x7E; + decodedFrameLen++; + continue; + } else if (byteRead == 0x5D) { + *(rxBuf + decodedFrameLen) = 0x7D; + decodedFrameLen++; + continue; + } else { + sif::error << "rwSpiCallback::spiCallback: Invalid substitute" << std::endl; + closeSpi(gpioId, gpioIF, mutex); + result = RwHandler::INVALID_SUBSTITUTE; + break; + } + } else { + *(rxBuf + decodedFrameLen) = byteRead; + decodedFrameLen++; + continue; } - if(mutex->unlockMutex() != HasReturnvaluesIF::RETURN_OK) { - sif::error << "rwSpiCallback::closeSpi: Failed to unlock mutex" << std::endl;; + + /** + * There might be the unlikely case that each byte in a get-telemetry reply has been + * replaced by its substitute. Than the next byte must correspond to the end sign 0x7E. + * Otherwise there might be something wrong. + */ + if (decodedFrameLen == replyBufferSize) { + if (read(fileDescriptor, &byteRead, 1) != 1) { + sif::error << "rwSpiCallback::spiCallback: Failed to read last byte" << std::endl; + result = RwHandler::SPI_READ_FAILURE; + break; + } + if (byteRead != 0x7E) { + sif::error << "rwSpiCallback::spiCallback: Missing end sign 0x7E" << std::endl; + decodedFrameLen--; + result = RwHandler::MISSING_END_SIGN; + break; + } } + result = HasReturnvaluesIF::RETURN_OK; + } + + cookie->setTransferSize(decodedFrameLen); + + closeSpi(gpioId, gpioIF, mutex); + + return result; } + +void closeSpi(gpioId_t gpioId, GpioIF* gpioIF, MutexIF* mutex) { + if (gpioId != gpio::NO_GPIO) { + if (gpioIF->pullHigh(gpioId) != HasReturnvaluesIF::RETURN_OK) { + sif::error << "closeSpi: Failed to pull chip select high" << std::endl; + } + } + if (mutex->unlockMutex() != HasReturnvaluesIF::RETURN_OK) { + sif::error << "rwSpiCallback::closeSpi: Failed to unlock mutex" << std::endl; + ; + } } +} // namespace rwSpiCallback diff --git a/bsp_q7s/callbacks/rwSpiCallback.h b/bsp_q7s/callbacks/rwSpiCallback.h index 8952f873..843d5b80 100644 --- a/bsp_q7s/callbacks/rwSpiCallback.h +++ b/bsp_q7s/callbacks/rwSpiCallback.h @@ -2,9 +2,8 @@ #define BSP_Q7S_RW_SPI_CALLBACK_H_ #include "fsfw/returnvalues/HasReturnvaluesIF.h" -#include "fsfw_hal/linux/spi/SpiComIF.h" #include "fsfw_hal/common/gpio/GpioCookie.h" - +#include "fsfw_hal/linux/spi/SpiComIF.h" namespace rwSpiCallback { @@ -31,8 +30,8 @@ static constexpr uint8_t FLAG_BYTE = 0x7E; * To switch between the to SPI peripherals, an EMIO is used which will also be controlled * by this function. */ -ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sendData, - size_t sendLen, void* args); +ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sendData, + size_t sendLen, void* args); /** * @brief This function closes a spi session. Pulls the chip select to high an releases the @@ -43,5 +42,5 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sen */ void closeSpi(gpioId_t gpioId, GpioIF* gpioIF, MutexIF* mutex); -} +} // namespace rwSpiCallback #endif /* BSP_Q7S_RW_SPI_CALLBACK_H_ */ diff --git a/bsp_q7s/comIF/CMakeLists.txt b/bsp_q7s/comIF/CMakeLists.txt index 0599b73f..fe4910f2 100644 --- a/bsp_q7s/comIF/CMakeLists.txt +++ b/bsp_q7s/comIF/CMakeLists.txt @@ -1,4 +1,4 @@ -target_sources(${TARGET_NAME} PRIVATE +target_sources(${OBSW_NAME} PRIVATE ) diff --git a/bsp_q7s/core/CMakeLists.txt b/bsp_q7s/core/CMakeLists.txt index fc397f2f..8731b7a3 100644 --- a/bsp_q7s/core/CMakeLists.txt +++ b/bsp_q7s/core/CMakeLists.txt @@ -1,6 +1,10 @@ -target_sources(${TARGET_NAME} PRIVATE +target_sources(${OBSW_NAME} PRIVATE CoreController.cpp obsw.cpp InitMission.cpp ObjectFactory.cpp ) + +target_sources(${SIMPLE_OBSW_NAME} PRIVATE + InitMission.cpp +) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 271ec508..b0b7213c 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -1,1171 +1,1692 @@ #include "CoreController.h" + +#include + #include "OBSWConfig.h" #include "OBSWVersion.h" -#include "watchdogConf.h" - -#include "fsfw/FSFWVersion.h" -#include "fsfw/timemanager/Stopwatch.h" #include "fsfw/serviceinterface/ServiceInterface.h" +#include "fsfw/timemanager/Stopwatch.h" +#include "fsfw/version.h" +#include "watchdogConf.h" #if OBSW_USE_TMTC_TCP_BRIDGE == 0 #include "fsfw/osal/common/UdpTmTcBridge.h" #else #include "fsfw/osal/common/TcpTmTcServer.h" #endif - -#include "bsp_q7s/memory/scratchApi.h" -#include "bsp_q7s/memory/SdCardManager.h" - #include #include #include -CoreController::Chip CoreController::CURRENT_CHIP = Chip::NO_CHIP; -CoreController::Copy CoreController::CURRENT_COPY = Copy::NO_COPY; +#include "bsp_q7s/memory/SdCardManager.h" +#include "bsp_q7s/memory/scratchApi.h" +#include "bsp_q7s/xadc/Xadc.h" -CoreController::CoreController(object_id_t objectId): - ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), opDivider(5) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - try { - result = initWatchdogFifo(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::CoreController: Watchdog FIFO init failed" << - std::endl; - } - sdcMan = SdCardManager::instance(); - if(sdcMan == nullptr) { - sif::error << "CoreController::CoreController: SD card manager invalid!" << std::endl; - } +xsc::Chip CoreController::CURRENT_CHIP = xsc::Chip::NO_CHIP; +xsc::Copy CoreController::CURRENT_COPY = xsc::Copy::NO_COPY; - if(not BLOCKING_SD_INIT) { - sdcMan->setBlocking(false); - } - sdStateMachine(); - - result = initBootCopy(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::CoreController: Boot copy init" << std::endl; - } +CoreController::CoreController(object_id_t objectId) + : ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), opDivider(5), hkSet(this) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + try { + result = initWatchdogFifo(); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::CoreController: Watchdog FIFO init failed" << std::endl; } - catch(const std::filesystem::filesystem_error& e) { - sif::error << "CoreController::CoreController: Failed with exception " << - e.what() << std::endl; + sdcMan = SdCardManager::instance(); + if (sdcMan == nullptr) { + sif::error << "CoreController::CoreController: SD card manager invalid!" << std::endl; } + + if (not BLOCKING_SD_INIT) { + sdcMan->setBlocking(false); + } + sdStateMachine(); + + result = initBootCopy(); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::CoreController: Boot copy init" << std::endl; + } + } catch (const std::filesystem::filesystem_error &e) { + sif::error << "CoreController::CoreController: Failed with exception " << e.what() << std::endl; + } } ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { - return ExtendedControllerBase::handleCommandMessage(message); + return ExtendedControllerBase::handleCommandMessage(message); } void CoreController::performControlOperation() { - performWatchdogControlOperation(); - sdStateMachine(); + performWatchdogControlOperation(); + sdStateMachine(); + performMountedSdCardOperations(); + readHkData(); } ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, - LocalDataPoolManager &poolManager) { - return HasReturnvaluesIF::RETURN_OK; + LocalDataPoolManager &poolManager) { + localDataPoolMap.emplace(core::TEMPERATURE, new PoolEntry({0})); + localDataPoolMap.emplace(core::PS_VOLTAGE, new PoolEntry({0})); + localDataPoolMap.emplace(core::PL_VOLTAGE, new PoolEntry({0})); + return HasReturnvaluesIF::RETURN_OK; } -LocalPoolDataSetBase* CoreController::getDataSetHandle(sid_t sid) { - return nullptr; +LocalPoolDataSetBase *CoreController::getDataSetHandle(sid_t sid) { + if (sid.ownerSetId == core::HK_SET_ID) { + return &hkSet; + } + return nullptr; } ReturnValue_t CoreController::initialize() { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - result = scratch::writeNumber(scratch::ALLOC_FAILURE_COUNT, 0); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::initialize: Setting up alloc failure " - "count failed" << std::endl; - } + result = scratch::writeNumber(scratch::ALLOC_FAILURE_COUNT, 0); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::initialize: Setting up alloc failure " + "count failed" + << std::endl; + } - sdStateMachine(); - return ExtendedControllerBase::initialize(); + sdStateMachine(); + + triggerEvent(REBOOT_SW, CURRENT_CHIP, CURRENT_COPY); + return ExtendedControllerBase::initialize(); } ReturnValue_t CoreController::initializeAfterTaskCreation() { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - if(BLOCKING_SD_INIT) { - ReturnValue_t result = initSdCardBlocking(); - if(result != HasReturnvaluesIF::RETURN_OK and result != SdCardManager::ALREADY_MOUNTED) { - sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if (BLOCKING_SD_INIT) { + ReturnValue_t result = initSdCardBlocking(); + if (result != HasReturnvaluesIF::RETURN_OK and result != SdCardManager::ALREADY_MOUNTED) { + sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; + } + } + sdStateMachine(); + performMountedSdCardOperations(); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; + } + // Add script folder to path + char *currentEnvPath = getenv("PATH"); + std::string updatedEnvPath = std::string(currentEnvPath) + ":/home/root/scripts"; + setenv("PATH", updatedEnvPath.c_str(), true); + updateProtInfo(); + initPrint(); + ExtendedControllerBase::initializeAfterTaskCreation(); + return result; +} + +ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t *data, size_t size) { + switch (actionId) { + case (LIST_DIRECTORY_INTO_FILE): { + return actionListDirectoryIntoFile(actionId, commandedBy, data, size); + } + case (SWITCH_REBOOT_FILE_HANDLING): { + if (size < 1) { + return HasActionsIF::INVALID_PARAMETERS; + } + std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + // Disable the reboot file mechanism + parseRebootFile(path, rebootFile); + if (data[0] == 0) { + rebootFile.enabled = false; + rewriteRebootFile(rebootFile); + } else if (data[0] == 1) { + rebootFile.enabled = true; + rewriteRebootFile(rebootFile); + } else { + return HasActionsIF::INVALID_PARAMETERS; + } + return HasActionsIF::EXECUTION_FINISHED; + } + case (RESET_REBOOT_COUNTERS): { + if (size == 0) { + resetRebootCount(xsc::ALL_CHIP, xsc::ALL_COPY); + } else if (size == 2) { + if (data[0] > 1 or data[1] > 1) { + return HasActionsIF::INVALID_PARAMETERS; } + resetRebootCount(static_cast(data[0]), static_cast(data[1])); + } + return HasActionsIF::EXECUTION_FINISHED; } - sdStateMachine(); - result = initVersionFile(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; + case (SWITCH_IMG_LOCK): { + if (size != 3) { + return HasActionsIF::INVALID_PARAMETERS; + } + if (data[1] > 1 or data[2] > 1) { + return HasActionsIF::INVALID_PARAMETERS; + } + setRebootMechanismLock(data[0], static_cast(data[1]), + static_cast(data[2])); + return HasActionsIF::EXECUTION_FINISHED; } - // Add script folder to path - char* currentEnvPath = getenv("PATH"); - std::string updatedEnvPath = std::string(currentEnvPath) + ":/home/root/scripts"; - setenv("PATH", updatedEnvPath.c_str(), true); - updateProtInfo(); - initPrint(); - return result; + case (SET_MAX_REBOOT_CNT): { + if (size < 1) { + return HasActionsIF::INVALID_PARAMETERS; + } + std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + // Disable the reboot file mechanism + parseRebootFile(path, rebootFile); + rebootFile.maxCount = data[0]; + rewriteRebootFile(rebootFile); + return HasActionsIF::EXECUTION_FINISHED; + } + case (REBOOT_OBC): { + return actionPerformReboot(data, size); + } + default: { + return HasActionsIF::INVALID_ACTION_ID; + } + } } ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t *msToReachTheMode) { - return HasReturnvaluesIF::RETURN_OK; + uint32_t *msToReachTheMode) { + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t CoreController::initSdCardBlocking() { - // Create update status file - ReturnValue_t result = sdcMan->updateSdCardStateFile(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::initialize: Updating SD card state file failed" - << std::endl; - } + // Create update status file + ReturnValue_t result = sdcMan->updateSdCardStateFile(); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::initialize: Updating SD card state file failed" << std::endl; + } #if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE - sif::info << "No SD card initialization will be performed" << std::endl; - return HasReturnvaluesIF::RETURN_OK; + sif::info << "No SD card initialization will be performed" << std::endl; + return HasReturnvaluesIF::RETURN_OK; #else - result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Getting SD card activity status failed" << std::endl; - } + result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Getting SD card activity status failed" << std::endl; + } #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT - determinePreferredSdCard(); - updateSdInfoOther(); - sif::info << "Cold redundant SD card configuration, preferred SD card: " << - static_cast(sdInfo.pref) << std::endl; - result = sdColdRedundantBlockingInit(); - // Update status file - sdcMan->updateSdCardStateFile(); - return result; + determinePreferredSdCard(); + updateSdInfoOther(); + sif::info << "Cold redundant SD card configuration, preferred SD card: " + << static_cast(sdInfo.pref) << std::endl; + result = sdColdRedundantBlockingInit(); + // Update status file + sdcMan->updateSdCardStateFile(); + return result; #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT - sif::info << "Hot redundant SD card configuration" << std::endl; - sdCardSetup(sd::SdCard::SLOT_0, sd::SdState::MOUNTED, "0", false); - sdCardSetup(sd::SdCard::SLOT_1, sd::SdState::MOUNTED, "1", false); - // Update status file - sdcMan->updateSdCardStateFile(); - return HasReturnvaluesIF::RETURN_OK; + sif::info << "Hot redundant SD card configuration" << std::endl; + sdCardSetup(sd::SdCard::SLOT_0, sd::SdState::MOUNTED, "0", false); + sdCardSetup(sd::SdCard::SLOT_1, sd::SdState::MOUNTED, "1", false); + // Update status file + sdcMan->updateSdCardStateFile(); + return HasReturnvaluesIF::RETURN_OK; #endif #endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ - } ReturnValue_t CoreController::sdStateMachine() { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - SdCardManager::Operations operation; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + SdCardManager::Operations operation; - if(sdInfo.state == SdStates::IDLE) { - // Nothing to do - return result; - } + if (sdInfo.state == SdStates::IDLE) { + // Nothing to do + return result; + } - if(sdInfo.state == SdStates::START) { - // Init will be performed by separate function - if(BLOCKING_SD_INIT) { - sdInfo.state = SdStates::IDLE; - sdInfo.initFinished = true; - return result; - } - else { - // Still update SD state file + if (sdInfo.state == SdStates::START) { + // Init will be performed by separate function + if (BLOCKING_SD_INIT) { + sdInfo.state = SdStates::IDLE; + sdInfo.initFinished = true; + return result; + } else { + // Still update SD state file #if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE - sdInfo.state = SdStates::UPDATE_INFO; + sdInfo.state = SdStates::UPDATE_INFO; #else - sdInfo.cycleCount = 0; - sdInfo.commandExecuted = false; - sdInfo.state = SdStates::GET_INFO; + sdInfo.cycleCount = 0; + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::GET_INFO; #endif - } } + } - // This lambda checks the non-blocking operation and assigns the new state on success. - // It returns true for an operation success and false otherwise - auto nonBlockingOpChecking = [&](SdStates newStateOnSuccess, - uint16_t maxCycleCount, std::string opPrintout) { - SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); - if(status == SdCardManager::OpStatus::SUCCESS) { - sdInfo.state = newStateOnSuccess; - sdInfo.commandExecuted = false; - sdInfo.cycleCount = 0; - return true; - } - else if(sdInfo.cycleCount > 4) { - sif::warning << "CoreController::sdInitStateMachine: " << opPrintout << - " takes too long" << std::endl; - return false; - } - return false; - }; - - if(sdInfo.state == SdStates::GET_INFO) { - if(not sdInfo.commandExecuted) { - // Create update status file - result = sdcMan->updateSdCardStateFile(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::initialize: Updating SD card state file failed" - << std::endl; - } - sdInfo.commandExecuted = true; - } - else { - nonBlockingOpChecking(SdStates::SET_STATE_SELF, 4, "Updating SDC file"); - } + // This lambda checks the non-blocking operation and assigns the new state on success. + // It returns true for an operation success and false otherwise + auto nonBlockingOpChecking = [&](SdStates newStateOnSuccess, uint16_t maxCycleCount, + std::string opPrintout) { + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if (status == SdCardManager::OpStatus::SUCCESS) { + sdInfo.state = newStateOnSuccess; + sdInfo.commandExecuted = false; + sdInfo.cycleCount = 0; + return true; + } else if (sdInfo.cycleCount > 4) { + sif::warning << "CoreController::sdInitStateMachine: " << opPrintout << " takes too long" + << std::endl; + return false; } + return false; + }; - if(sdInfo.state == SdStates::SET_STATE_SELF) { - if(not sdInfo.commandExecuted) { - result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); - determinePreferredSdCard(); - updateSdInfoOther(); - if(sdInfo.pref != sd::SdCard::SLOT_0 and sdInfo.pref != sd::SdCard::SLOT_1) { - sif::warning << "Preferred SD card invalid. Setting to card 0.." << std::endl; - sdInfo.pref = sd::SdCard::SLOT_0; - } - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Getting SD card activity status failed" << std::endl; - } + if (sdInfo.state == SdStates::GET_INFO) { + if (not sdInfo.commandExecuted) { + // Create update status file + result = sdcMan->updateSdCardStateFile(); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::initialize: Updating SD card state file failed" + << std::endl; + } + sdInfo.commandExecuted = true; + } else { + nonBlockingOpChecking(SdStates::SET_STATE_SELF, 4, "Updating SDC file"); + } + } + + if (sdInfo.state == SdStates::SET_STATE_SELF) { + if (not sdInfo.commandExecuted) { + result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); + determinePreferredSdCard(); + updateSdInfoOther(); + if (sdInfo.pref != sd::SdCard::SLOT_0 and sdInfo.pref != sd::SdCard::SLOT_1) { + sif::warning << "Preferred SD card invalid. Setting to card 0.." << std::endl; + sdInfo.pref = sd::SdCard::SLOT_0; + } + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Getting SD card activity status failed" << std::endl; + } #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT - sif::info << "Cold redundant SD card configuration, preferred SD card: " << - static_cast(sdInfo.pref) << std::endl; + sif::info << "Cold redundant SD card configuration, preferred SD card: " + << static_cast(sdInfo.pref) << std::endl; #endif - if(sdInfo.prefState == sd::SdState::MOUNTED) { + if (sdInfo.prefState == sd::SdState::MOUNTED) { #if OBSW_VERBOSE_LEVEL >= 1 - std::string mountString; - if(sdInfo.pref == sd::SdCard::SLOT_0) { - mountString = SdCardManager::SD_0_MOUNT_POINT; - } - else { - mountString = SdCardManager::SD_1_MOUNT_POINT; - } - sif::info << "SD card " << sdInfo.prefChar << " already on and mounted at " << - mountString << std::endl; + std::string mountString; + if (sdInfo.pref == sd::SdCard::SLOT_0) { + mountString = SdCardManager::SD_0_MOUNT_POINT; + } else { + mountString = SdCardManager::SD_1_MOUNT_POINT; + } + sif::info << "SD card " << sdInfo.prefChar << " already on and mounted at " << mountString + << std::endl; #endif - sdInfo.state = SdStates::DETERMINE_OTHER; - } - else if(sdInfo.prefState == sd::SdState::OFF) { - sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar, false); - sdInfo.commandExecuted = true; - } - else if(sdInfo.prefState == sd::SdState::ON) { - sdInfo.state = SdStates::MOUNT_SELF; - } - } - else { - if(nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state")) { - sdInfo.prefState = sd::SdState::ON; - currentStateSetter(sdInfo.pref, sd::SdState::ON); - } - } + sdInfo.state = SdStates::DETERMINE_OTHER; + } else if (sdInfo.prefState == sd::SdState::OFF) { + sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar, false); + sdInfo.commandExecuted = true; + } else if (sdInfo.prefState == sd::SdState::ON) { + sdInfo.state = SdStates::MOUNT_SELF; + } + } else { + if (nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state")) { + sdInfo.prefState = sd::SdState::ON; + currentStateSetter(sdInfo.pref, sd::SdState::ON); + } } + } - if(sdInfo.state == SdStates::MOUNT_SELF) { - if(not sdInfo.commandExecuted) { - result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); - sdInfo.commandExecuted = true; - } - else { - if(nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card")) { - sdInfo.prefState = sd::SdState::MOUNTED; - currentStateSetter(sdInfo.pref, sd::SdState::MOUNTED); - } - } + if (sdInfo.state == SdStates::MOUNT_SELF) { + if (not sdInfo.commandExecuted) { + result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + sdInfo.commandExecuted = true; + } else { + if (nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card")) { + sdInfo.prefState = sd::SdState::MOUNTED; + currentStateSetter(sdInfo.pref, sd::SdState::MOUNTED); + } } + } - if(sdInfo.state == SdStates::DETERMINE_OTHER) { - // Determine whether any additional operations have to be done for the other SD card - // 1. Cold redundant case: Other SD card needs to be unmounted and switched off - // 2. Hot redundant case: Other SD card needs to be mounted and switched on + if (sdInfo.state == SdStates::DETERMINE_OTHER) { + // Determine whether any additional operations have to be done for the other SD card + // 1. Cold redundant case: Other SD card needs to be unmounted and switched off + // 2. Hot redundant case: Other SD card needs to be mounted and switched on #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT - if(sdInfo.otherState == sd::SdState::ON) { - sdInfo.state = SdStates::SET_STATE_OTHER; - } - else if(sdInfo.otherState == sd::SdState::MOUNTED) { - sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; - } - else { - // Is already off, update info, but with a small delay - sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; - } -#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT - if(sdInfo.otherState == sd::SdState::OFF) { - sdInfo.state = SdStates::SET_STATE_OTHER; - } - else if(sdInfo.otherState == sd::SdState::ON) { - sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; - } - else { - // Is already on and mounted, update info - sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; - } -#endif + if (sdInfo.otherState == sd::SdState::ON) { + sdInfo.state = SdStates::SET_STATE_OTHER; + } else if (sdInfo.otherState == sd::SdState::MOUNTED) { + sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; + } else { + // Is already off, update info, but with a small delay + sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; } +#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT + if (sdInfo.otherState == sd::SdState::OFF) { + sdInfo.state = SdStates::SET_STATE_OTHER; + } else if (sdInfo.otherState == sd::SdState::ON) { + sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; + } else { + // Is already on and mounted, update info + sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; + } +#endif + } - if(sdInfo.state == SdStates::SET_STATE_OTHER) { - // Set state of other SD card to ON or OFF, depending on redundancy mode + if (sdInfo.state == SdStates::SET_STATE_OTHER) { + // Set state of other SD card to ON or OFF, depending on redundancy mode #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT - if(not sdInfo.commandExecuted) { - result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar, false); - sdInfo.commandExecuted = true; - } - else { - if(nonBlockingOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10, - "Switching off other SD card")) { - sdInfo.otherState = sd::SdState::OFF; - currentStateSetter(sdInfo.other, sd::SdState::OFF); - } - } -#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT - if(not sdInfo.commandExecuted) { - result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar, false); - sdInfo.commandExecuted = true; - } - else { - if(nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, - "Switching on other SD card")) { - sdInfo.otherState = sd::SdState::ON; - currentStateSetter(sdInfo.other, sd::SdState::ON); - } - } -#endif + if (not sdInfo.commandExecuted) { + result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar, false); + sdInfo.commandExecuted = true; + } else { + if (nonBlockingOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10, + "Switching off other SD card")) { + sdInfo.otherState = sd::SdState::OFF; + currentStateSetter(sdInfo.other, sd::SdState::OFF); + } } +#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT + if (not sdInfo.commandExecuted) { + result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar, false); + sdInfo.commandExecuted = true; + } else { + if (nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, "Switching on other SD card")) { + sdInfo.otherState = sd::SdState::ON; + currentStateSetter(sdInfo.other, sd::SdState::ON); + } + } +#endif + } - if(sdInfo.state == SdStates::MOUNT_UNMOUNT_OTHER) { - // Mount or unmount other SD card, depending on redundancy mode + if (sdInfo.state == SdStates::MOUNT_UNMOUNT_OTHER) { + // Mount or unmount other SD card, depending on redundancy mode #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT - if(not sdInfo.commandExecuted) { - result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); - sdInfo.commandExecuted = true; - } - else { - if(nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card")) { - sdInfo.otherState = sd::SdState::ON; - currentStateSetter(sdInfo.other, sd::SdState::ON); - } - } + if (not sdInfo.commandExecuted) { + result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); + sdInfo.commandExecuted = true; + } else { + if (nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card")) { + sdInfo.otherState = sd::SdState::ON; + currentStateSetter(sdInfo.other, sd::SdState::ON); + } + } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT - if(not sdInfo.commandExecuted) { - result = sdCardSetup(sdInfo.other, sd::SdState::MOUNTED, sdInfo.otherChar); - sdInfo.commandExecuted = true; - } - else { - if(nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card")) { - sdInfo.otherState = sd::SdState::MOUNTED; - currentStateSetter(sdInfo.other, sd::SdState::MOUNTED); - } - } + if (not sdInfo.commandExecuted) { + result = sdCardSetup(sdInfo.other, sd::SdState::MOUNTED, sdInfo.otherChar); + sdInfo.commandExecuted = true; + } else { + if (nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card")) { + sdInfo.otherState = sd::SdState::MOUNTED; + currentStateSetter(sdInfo.other, sd::SdState::MOUNTED); + } + } #endif - } + } - if(sdInfo.state == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) { - sdInfo.state = SdStates::UPDATE_INFO; + if (sdInfo.state == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) { + sdInfo.state = SdStates::UPDATE_INFO; + } else if (sdInfo.state == SdStates::UPDATE_INFO) { + // It is assumed that all tasks are running by the point this section is reached. + // Therefore, perform this operation in blocking mode because it does not take long + // and the ready state of the SD card is available sooner + sdcMan->setBlocking(true); + // Update status file + result = sdcMan->updateSdCardStateFile(); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::initialize: Updating SD card state file failed" << std::endl; } - else if(sdInfo.state == SdStates::UPDATE_INFO) { - // It is assumed that all tasks are running by the point this section is reached. - // Therefore, perform this operation in blocking mode because it does not take long - // and the ready state of the SD card is available sooner - sdcMan->setBlocking(true); - // Update status file - result = sdcMan->updateSdCardStateFile(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::initialize: Updating SD card state file failed" - << std::endl; - } - sdInfo.commandExecuted = false; - sdInfo.state = SdStates::IDLE; - sdInfo.cycleCount = 0; - sdcMan->setBlocking(false); - sdcMan->getSdCardActiveStatus(sdInfo.currentState); - if(not sdInfo.initFinished) { - updateSdInfoOther(); - sdInfo.initFinished = true; - sif::info << "SD card initialization finished" << std::endl; - } + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::IDLE; + sdInfo.cycleCount = 0; + sdcMan->setBlocking(false); + sdcMan->getSdCardActiveStatus(sdInfo.currentState); + if (not sdInfo.initFinished) { + updateSdInfoOther(); + sdInfo.initFinished = true; + sif::info << "SD card initialization finished" << std::endl; } + } - if(sdInfo.state == SdStates::SET_STATE_FROM_COMMAND) { - if(not sdInfo.commandExecuted) { - executeNextExternalSdCommand(); - } - else { - checkExternalSdCommandStatus(); - } + if (sdInfo.state == SdStates::SET_STATE_FROM_COMMAND) { + if (not sdInfo.commandExecuted) { + executeNextExternalSdCommand(); + } else { + checkExternalSdCommandStatus(); } + } - sdInfo.cycleCount++; - return HasReturnvaluesIF::RETURN_OK; + sdInfo.cycleCount++; + return HasReturnvaluesIF::RETURN_OK; } void CoreController::executeNextExternalSdCommand() { - std::string sdChar; - sd::SdState currentStateOfCard = sd::SdState::OFF; - if(sdInfo.commandedCard == sd::SdCard::SLOT_0) { - sdChar = "0"; - currentStateOfCard = sdInfo.currentState.first; + std::string sdChar; + sd::SdState currentStateOfCard = sd::SdState::OFF; + if (sdInfo.commandedCard == sd::SdCard::SLOT_0) { + sdChar = "0"; + currentStateOfCard = sdInfo.currentState.first; + } else { + sdChar = "1"; + currentStateOfCard = sdInfo.currentState.second; + } + if (currentStateOfCard == sd::SdState::OFF) { + if (sdInfo.commandedState == sd::SdState::ON) { + sdInfo.currentlyCommandedState = sdInfo.commandedState; + } else if (sdInfo.commandedState == sd::SdState::MOUNTED) { + sdInfo.currentlyCommandedState = sd::SdState::ON; + } else { + // SD card is already on target state + sdInfo.commandFinished = true; + sdInfo.state = SdStates::IDLE; } - else { - sdChar = "1"; - currentStateOfCard = sdInfo.currentState.second; + } else if (currentStateOfCard == sd::SdState::ON) { + if (sdInfo.commandedState == sd::SdState::OFF or + sdInfo.commandedState == sd::SdState::MOUNTED) { + sdInfo.currentlyCommandedState = sdInfo.commandedState; + } else { + // Already on target state + sdInfo.commandFinished = true; + sdInfo.state = SdStates::IDLE; } - if(currentStateOfCard == sd::SdState::OFF) { - if(sdInfo.commandedState == sd::SdState::ON) { - sdInfo.currentlyCommandedState = sdInfo.commandedState; - } - else if(sdInfo.commandedState == sd::SdState::MOUNTED) { - sdInfo.currentlyCommandedState = sd::SdState::ON; - } - else { - // SD card is already on target state - sdInfo.commandFinished = true; - sdInfo.state = SdStates::IDLE; - } + } else if (currentStateOfCard == sd::SdState::MOUNTED) { + if (sdInfo.commandedState == sd::SdState::ON) { + sdInfo.currentlyCommandedState = sdInfo.commandedState; + } else if (sdInfo.commandedState == sd::SdState::OFF) { + // This causes an unmount in sdCardSetup + sdInfo.currentlyCommandedState = sd::SdState::ON; + } else { + sdInfo.commandFinished = true; } - else if(currentStateOfCard == sd::SdState::ON) { - if(sdInfo.commandedState == sd::SdState::OFF or - sdInfo.commandedState == sd::SdState::MOUNTED) { - sdInfo.currentlyCommandedState = sdInfo.commandedState; - } - else { - // Already on target state - sdInfo.commandFinished = true; - sdInfo.state = SdStates::IDLE; - } - } - else if(currentStateOfCard == sd::SdState::MOUNTED) { - if(sdInfo.commandedState == sd::SdState::ON) { - sdInfo.currentlyCommandedState = sdInfo.commandedState; - } - else if(sdInfo.commandedState == sd::SdState::OFF) { - // This causes an unmount in sdCardSetup - sdInfo.currentlyCommandedState = sd::SdState::ON; - } - else { - sdInfo.commandFinished = true; - } - } - sdCardSetup(sdInfo.commandedCard, sdInfo.commandedState, sdChar); - sdInfo.commandExecuted = true; + } + sdCardSetup(sdInfo.commandedCard, sdInfo.commandedState, sdChar); + sdInfo.commandExecuted = true; } void CoreController::checkExternalSdCommandStatus() { - SdCardManager::Operations operation; - SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); - if(status == SdCardManager::OpStatus::SUCCESS) { - if(sdInfo.currentlyCommandedState == sdInfo.commandedState) { - sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; - sdInfo.commandFinished = true; - } - else { - // stay on same state machine state because the target state was not reached yet. - sdInfo.cycleCount = 0; - } - currentStateSetter(sdInfo.commandedCard, sdInfo.currentlyCommandedState); - sdInfo.commandExecuted = false; - } - else if(sdInfo.cycleCount > 4) { - sif::warning << "CoreController::sdStateMachine: Commanding SD state " - "takes too long" << std::endl; + SdCardManager::Operations operation; + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if (status == SdCardManager::OpStatus::SUCCESS) { + if (sdInfo.currentlyCommandedState == sdInfo.commandedState) { + sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; + sdInfo.commandFinished = true; + } else { + // stay on same state machine state because the target state was not reached yet. + sdInfo.cycleCount = 0; } + currentStateSetter(sdInfo.commandedCard, sdInfo.currentlyCommandedState); + sdInfo.commandExecuted = false; + } else if (sdInfo.cycleCount > 4) { + sif::warning << "CoreController::sdStateMachine: Commanding SD state " + "takes too long" + << std::endl; + } } void CoreController::currentStateSetter(sd::SdCard sdCard, sd::SdState newState) { - if(sdCard == sd::SdCard::SLOT_0) { - sdInfo.currentState.first = newState; - } - else { - sdInfo.currentState.second = newState; - } + if (sdCard == sd::SdCard::SLOT_0) { + sdInfo.currentState.first = newState; + } else { + sdInfo.currentState.second = newState; + } } ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, - std::string sdChar, bool printOutput) { - std::string mountString; - sdcMan->setPrintCommandOutput(printOutput); - if(sdCard == sd::SdCard::SLOT_0) { - mountString = SdCardManager::SD_0_MOUNT_POINT; - } - else { - mountString = SdCardManager::SD_1_MOUNT_POINT; - } + std::string sdChar, bool printOutput) { + std::string mountString; + sdcMan->setPrintCommandOutput(printOutput); + if (sdCard == sd::SdCard::SLOT_0) { + mountString = SdCardManager::SD_0_MOUNT_POINT; + } else { + mountString = SdCardManager::SD_1_MOUNT_POINT; + } - sd::SdState state = sd::SdState::OFF; - if(sdCard == sd::SdCard::SLOT_0) { - state = sdInfo.currentState.first; - } - else { - state = sdInfo.currentState.second; - } - if(state == sd::SdState::MOUNTED) { - if(targetState == sd::SdState::OFF) { - sif::info << "Switching off SD card " << sdChar << std::endl; - return sdcMan->switchOffSdCard(sdCard, true, &sdInfo.currentState); - } - else if(targetState == sd::SdState::ON) { - sif::info << "Unmounting SD card " << sdChar << std::endl; - return sdcMan->unmountSdCard(sdCard); - } - else { - if(std::filesystem::exists(mountString)) { - sif::info << "SD card " << sdChar << " already on and mounted at " << - mountString << std::endl; - return SdCardManager::ALREADY_MOUNTED; - } - sif::error << "SD card mounted but expected mount point " << - mountString << " not found!" << std::endl; - return SdCardManager::MOUNT_ERROR; - } + sd::SdState state = sd::SdState::OFF; + if (sdCard == sd::SdCard::SLOT_0) { + state = sdInfo.currentState.first; + } else { + state = sdInfo.currentState.second; + } + if (state == sd::SdState::MOUNTED) { + if (targetState == sd::SdState::OFF) { + sif::info << "Switching off SD card " << sdChar << std::endl; + return sdcMan->switchOffSdCard(sdCard, true, &sdInfo.currentState); + } else if (targetState == sd::SdState::ON) { + sif::info << "Unmounting SD card " << sdChar << std::endl; + return sdcMan->unmountSdCard(sdCard); + } else { + if (std::filesystem::exists(mountString)) { + sif::info << "SD card " << sdChar << " already on and mounted at " << mountString + << std::endl; + return SdCardManager::ALREADY_MOUNTED; + } + sif::error << "SD card mounted but expected mount point " << mountString << " not found!" + << std::endl; + return SdCardManager::MOUNT_ERROR; } + } - if(state == sd::SdState::OFF) { - if(targetState == sd::SdState::MOUNTED) { - sif::info << "Switching on and mounting SD card " << sdChar << " at " << - mountString << std::endl; - return sdcMan->switchOnSdCard(sdCard, true, &sdInfo.currentState); - } - else if(targetState == sd::SdState::ON) { - sif::info << "Switching on SD card " << sdChar << std::endl; - return sdcMan->switchOnSdCard(sdCard, false, &sdInfo.currentState); - } + if (state == sd::SdState::OFF) { + if (targetState == sd::SdState::MOUNTED) { + sif::info << "Switching on and mounting SD card " << sdChar << " at " << mountString + << std::endl; + return sdcMan->switchOnSdCard(sdCard, true, &sdInfo.currentState); + } else if (targetState == sd::SdState::ON) { + sif::info << "Switching on SD card " << sdChar << std::endl; + return sdcMan->switchOnSdCard(sdCard, false, &sdInfo.currentState); } + } - else if(state == sd::SdState::ON) { - if(targetState == sd::SdState::MOUNTED) { - sif::info << "Mounting SD card " << sdChar << " at " << mountString << std::endl; - return sdcMan->mountSdCard(sdCard); - } - else if(targetState == sd::SdState::OFF) { - sif::info << "Switching off SD card " << sdChar << std::endl; - return sdcMan->switchOffSdCard(sdCard, false, &sdInfo.currentState); - } - } - else { - sif::warning << "CoreController::sdCardSetup: Invalid state for this call" << std::endl; - } - return HasReturnvaluesIF::RETURN_OK; -} - - -ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, - const uint8_t *data, size_t size) { - switch(actionId) { - case(LIST_DIRECTORY_INTO_FILE): { - return actionListDirectoryIntoFile(actionId, commandedBy, data, size); - } - case(REBOOT_OBC): { - return actionPerformReboot(data, size); - } - default: { - return HasActionsIF::INVALID_ACTION_ID; - } + else if (state == sd::SdState::ON) { + if (targetState == sd::SdState::MOUNTED) { + sif::info << "Mounting SD card " << sdChar << " at " << mountString << std::endl; + return sdcMan->mountSdCard(sdCard); + } else if (targetState == sd::SdState::OFF) { + sif::info << "Switching off SD card " << sdChar << std::endl; + return sdcMan->switchOffSdCard(sdCard, false, &sdInfo.currentState); } + } else { + sif::warning << "CoreController::sdCardSetup: Invalid state for this call" << std::endl; + } + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t CoreController::sdColdRedundantBlockingInit() { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); - if(result != SdCardManager::ALREADY_MOUNTED and result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Setting up preferred card " << sdInfo.otherChar << - " in cold redundant mode failed" << std::endl; - // Try other SD card and mark set up operation as failed - sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); - result = HasReturnvaluesIF::RETURN_FAILED; - } + result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + if (result != SdCardManager::ALREADY_MOUNTED and result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Setting up preferred card " << sdInfo.otherChar + << " in cold redundant mode failed" << std::endl; + // Try other SD card and mark set up operation as failed + sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + result = HasReturnvaluesIF::RETURN_FAILED; + } - if(result != HasReturnvaluesIF::RETURN_FAILED and sdInfo.otherState != sd::SdState::OFF) { - sif::info << "Switching off secondary SD card " << sdInfo.otherChar << std::endl; - // Switch off other SD card in cold redundant mode if setting up preferred one worked - // without issues - ReturnValue_t result2 = sdcMan->switchOffSdCard(sdInfo.other, - sdInfo.otherState, &sdInfo.currentState); - if(result2 != HasReturnvaluesIF::RETURN_OK and result2 != SdCardManager::ALREADY_OFF) { - sif::warning << "Switching off secondary SD card " << sdInfo.otherChar << - " in cold redundant mode failed" << std::endl; - } + if (result != HasReturnvaluesIF::RETURN_FAILED and sdInfo.otherState != sd::SdState::OFF) { + sif::info << "Switching off secondary SD card " << sdInfo.otherChar << std::endl; + // Switch off other SD card in cold redundant mode if setting up preferred one worked + // without issues + ReturnValue_t result2 = + sdcMan->switchOffSdCard(sdInfo.other, sdInfo.otherState, &sdInfo.currentState); + if (result2 != HasReturnvaluesIF::RETURN_OK and result2 != SdCardManager::ALREADY_OFF) { + sif::warning << "Switching off secondary SD card " << sdInfo.otherChar + << " in cold redundant mode failed" << std::endl; } - return result; + } + return result; } ReturnValue_t CoreController::incrementAllocationFailureCount() { - uint32_t count = 0; - ReturnValue_t result = scratch::readNumber(scratch::ALLOC_FAILURE_COUNT, count); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - count++; - return scratch::writeNumber(scratch::ALLOC_FAILURE_COUNT, count); + uint32_t count = 0; + ReturnValue_t result = scratch::readNumber(scratch::ALLOC_FAILURE_COUNT, count); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + count++; + return scratch::writeNumber(scratch::ALLOC_FAILURE_COUNT, count); } ReturnValue_t CoreController::initVersionFile() { + using namespace fsfw; + std::string unameFileName = "/tmp/uname_version.txt"; + // TODO: No -v flag for now. If the kernel version is used, need to cut off first few letters + std::string unameCmd = "uname -mnrso > " + unameFileName; + int result = std::system(unameCmd.c_str()); + if (result != 0) { + utility::handleSystemError(result, "CoreController::versionFileInit"); + } + std::ifstream unameFile(unameFileName); + std::string unameLine; + if (not std::getline(unameFile, unameLine)) { + sif::warning << "CoreController::versionFileInit: Retrieving uname line failed" << std::endl; + } - std::string unameFileName = "/tmp/uname_version.txt"; - // TODO: No -v flag for now. If the kernel version is used, need to cut off first few letters - std::string unameCmd = "uname -mnrso > " + unameFileName; - int result = std::system(unameCmd.c_str()); - if(result != 0) { - utility::handleSystemError(result, "CoreController::versionFileInit"); - } - std::ifstream unameFile(unameFileName); - std::string unameLine; - if(not std::getline(unameFile, unameLine)) { - sif::warning << "CoreController::versionFileInit: Retrieving uname line failed" - << std::endl; - } - - std::string fullObswVersionString = "OBSW: v" + std::to_string(SW_VERSION) + "." + - std::to_string(SW_SUBVERSION) + "." + std::to_string(SW_REVISION); - std::string fullFsfwVersionString = "FSFW: v" + std::to_string(FSFW_VERSION) + "." + - std::to_string(FSFW_SUBVERSION) + "." + std::to_string(FSFW_REVISION); - std::string systemString = "System: " + unameLine; - std::string mountPrefix = SdCardManager::instance()->getCurrentMountPrefix(); - std::string versionFilePath = mountPrefix + VERSION_FILE; - std::fstream versionFile; - - if(not std::filesystem::exists(versionFilePath)) { - sif::info << "Writing version file " << versionFilePath << ".." << std::endl; - versionFile.open(versionFilePath, std::ios_base::out); - versionFile << fullObswVersionString << std::endl; - versionFile << fullFsfwVersionString << std::endl; - versionFile << systemString << std::endl; - return HasReturnvaluesIF::RETURN_OK; - } - - // Check whether any version has changed - bool createNewFile = false; - versionFile.open(versionFilePath); - std::string currentVersionString; - uint8_t idx = 0; - while(std::getline(versionFile, currentVersionString)) { - if(idx == 0) { - if(currentVersionString != fullObswVersionString) { - sif::info << "OBSW version changed" << std::endl; - sif::info << "From " << currentVersionString << " to " << - fullObswVersionString << std::endl; - createNewFile = true; - } - } - else if(idx == 1) { - if(currentVersionString != fullFsfwVersionString) { - sif::info << "FSFW version changed" << std::endl; - sif::info << "From " << currentVersionString << " to " << - fullFsfwVersionString << std::endl; - createNewFile = true; - } - } - else if(idx == 2) { - if(currentVersionString != systemString) { - sif::info << "System version changed" << std::endl; - sif::info << "Old: " << currentVersionString << std::endl; - sif::info << "New: " << systemString << std::endl; - createNewFile = true; - } - } - else { - sif::warning << "Invalid version file! Rewriting it.." << std::endl; - createNewFile = true; - } - idx++; - } - - // Overwrite file if necessary - if(createNewFile) { - sif::info << "Rewriting version.txt file with updated versions.." << std::endl; - versionFile.close(); - versionFile.open(versionFilePath, std::ios_base::out | std::ios_base::trunc); - versionFile << fullObswVersionString << std::endl; - versionFile << fullFsfwVersionString << std::endl; - versionFile << systemString << std::endl; - } + std::string fullObswVersionString = "OBSW: v" + std::to_string(SW_VERSION) + "." + + std::to_string(SW_SUBVERSION) + "." + + std::to_string(SW_REVISION); + char versionString[16] = {}; + fsfw::FSFW_VERSION.getVersion(versionString, sizeof(versionString)); + std::string fullFsfwVersionString = "FSFW: v" + std::string(versionString); + std::string systemString = "System: " + unameLine; + std::string mountPrefix = SdCardManager::instance()->getCurrentMountPrefix(); + std::string versionFilePath = mountPrefix + VERSION_FILE; + std::fstream versionFile; + if (not std::filesystem::exists(versionFilePath)) { + sif::info << "Writing version file " << versionFilePath << ".." << std::endl; + versionFile.open(versionFilePath, std::ios_base::out); + versionFile << fullObswVersionString << std::endl; + versionFile << fullFsfwVersionString << std::endl; + versionFile << systemString << std::endl; return HasReturnvaluesIF::RETURN_OK; + } + + // Check whether any version has changed + bool createNewFile = false; + versionFile.open(versionFilePath); + std::string currentVersionString; + uint8_t idx = 0; + while (std::getline(versionFile, currentVersionString)) { + if (idx == 0) { + if (currentVersionString != fullObswVersionString) { + sif::info << "OBSW version changed" << std::endl; + sif::info << "From " << currentVersionString << " to " << fullObswVersionString + << std::endl; + createNewFile = true; + } + } else if (idx == 1) { + if (currentVersionString != fullFsfwVersionString) { + sif::info << "FSFW version changed" << std::endl; + sif::info << "From " << currentVersionString << " to " << fullFsfwVersionString + << std::endl; + createNewFile = true; + } + } else if (idx == 2) { + if (currentVersionString != systemString) { + sif::info << "System version changed" << std::endl; + sif::info << "Old: " << currentVersionString << std::endl; + sif::info << "New: " << systemString << std::endl; + createNewFile = true; + } + } else { + sif::warning << "Invalid version file! Rewriting it.." << std::endl; + createNewFile = true; + } + idx++; + } + + // Overwrite file if necessary + if (createNewFile) { + sif::info << "Rewriting version.txt file with updated versions.." << std::endl; + versionFile.close(); + versionFile.open(versionFilePath, std::ios_base::out | std::ios_base::trunc); + versionFile << fullObswVersionString << std::endl; + versionFile << fullFsfwVersionString << std::endl; + versionFile << systemString << std::endl; + } + + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t *data, size_t size) { - // TODO: Packet definition for clean deserialization - // 2 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with - // null termination, at least 7 bytes for minimum target file name /tmp/a with - // null termination. - if(size < 14) { - return HasActionsIF::INVALID_PARAMETERS; - } - // We could also make -l optional, but I can't think of a reason why to not use -l.. + MessageQueueId_t commandedBy, + const uint8_t *data, size_t size) { + // TODO: Packet definition for clean deserialization + // 2 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with + // null termination, at least 7 bytes for minimum target file name /tmp/a with + // null termination. + if (size < 14) { + return HasActionsIF::INVALID_PARAMETERS; + } + // We could also make -l optional, but I can't think of a reason why to not use -l.. - // This flag specifies to run ls with -a - bool aFlag = data[0]; - data += 1; - // This flag specifies to run ls with -R - bool RFlag = data[1]; - data += 1; + // This flag specifies to run ls with -a + bool aFlag = data[0]; + data += 1; + // This flag specifies to run ls with -R + bool RFlag = data[1]; + data += 1; - size_t remainingSize = size - 2; - // One larger for null termination, which prevents undefined behaviour if the sent - // strings are not 0 terminated properly - std::vector repoAndTargetFileBuffer(remainingSize + 1, 0); - std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize); - const char* currentCharPtr = reinterpret_cast(repoAndTargetFileBuffer.data()); - // Full target file name - std::string repoName(currentCharPtr); - size_t repoLength = repoName.length(); - // The other string needs to be at least one letter plus NULL termination to be valid at all - // The first string also needs to be NULL terminated, but the termination is not included - // in the string length, so this is subtracted from the remaining size as well - if(repoLength > remainingSize - 3) { - return HasActionsIF::INVALID_PARAMETERS; - } - // The file length will not include the NULL termination, so we skip it - currentCharPtr += repoLength + 1; - std::string targetFileName(currentCharPtr); - std::ostringstream oss; - oss << "ls -l"; - if(aFlag) { - oss << "a"; - } - if(RFlag) { - oss << "R"; - } + size_t remainingSize = size - 2; + // One larger for null termination, which prevents undefined behaviour if the sent + // strings are not 0 terminated properly + std::vector repoAndTargetFileBuffer(remainingSize + 1, 0); + std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize); + const char *currentCharPtr = reinterpret_cast(repoAndTargetFileBuffer.data()); + // Full target file name + std::string repoName(currentCharPtr); + size_t repoLength = repoName.length(); + // The other string needs to be at least one letter plus NULL termination to be valid at all + // The first string also needs to be NULL terminated, but the termination is not included + // in the string length, so this is subtracted from the remaining size as well + if (repoLength > remainingSize - 3) { + return HasActionsIF::INVALID_PARAMETERS; + } + // The file length will not include the NULL termination, so we skip it + currentCharPtr += repoLength + 1; + std::string targetFileName(currentCharPtr); + std::ostringstream oss; + oss << "ls -l"; + if (aFlag) { + oss << "a"; + } + if (RFlag) { + oss << "R"; + } - oss << " " << repoName << " > " << targetFileName; - int result = std::system(oss.str().c_str()); - if(result != 0) { - utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile"); - actionHelper.finish(false, commandedBy, actionId); - } - return HasReturnvaluesIF::RETURN_OK; + oss << " " << repoName << " > " << targetFileName; + int result = std::system(oss.str().c_str()); + if (result != 0) { + utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile"); + actionHelper.finish(false, commandedBy, actionId); + } + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t CoreController::initBootCopy() { - if(not std::filesystem::exists(CURR_COPY_FILE)) { - // Thils file is created by the systemd service eive-early-config so this should - // not happen normally - std::string cmd = "xsc_boot_copy > " + std::string(CURR_COPY_FILE); - int result = std::system(cmd.c_str()); - if(result != 0) { - utility::handleSystemError(result, "CoreController::initBootCopy"); - } + if (not std::filesystem::exists(CURR_COPY_FILE)) { + // This file is created by the systemd service eive-early-config so this should + // not happen normally + std::string cmd = "xsc_boot_copy > " + std::string(CURR_COPY_FILE); + int result = std::system(cmd.c_str()); + if (result != 0) { + utility::handleSystemError(result, "CoreController::initBootCopy"); } - std::ifstream file(CURR_COPY_FILE); - std::string line; - std::getline(file, line); - std::istringstream iss(line); - int value = 0; - iss >> value; - CURRENT_CHIP = static_cast(value); - iss >> value; - CURRENT_COPY = static_cast(value); - return HasReturnvaluesIF::RETURN_OK; + } + + getCurrentBootCopy(CURRENT_CHIP, CURRENT_COPY); + return HasReturnvaluesIF::RETURN_OK; } -void CoreController::getCurrentBootCopy(Chip &chip, Copy ©) { - // Not really thread-safe but it does not need to be - chip = CURRENT_CHIP; - copy = CURRENT_COPY; +void CoreController::getCurrentBootCopy(xsc::Chip &chip, xsc::Copy ©) { + xsc_libnor_chip_t xscChip; + xsc_libnor_copy_t xscCopy; + xsc_boot_get_chip_copy(&xscChip, &xscCopy); + // Not really thread-safe but it does not need to be + chip = static_cast(xscChip); + copy = static_cast(xscCopy); } ReturnValue_t CoreController::initWatchdogFifo() { - if(not std::filesystem::exists(watchdog::FIFO_NAME)) { - // Still return RETURN_OK for now - sif::info << "Watchdog FIFO " << watchdog::FIFO_NAME << " does not exist, can't initiate" << - " watchdog" << std::endl; - return HasReturnvaluesIF::RETURN_OK; - } - // Open FIFO write only and non-blocking to prevent SW from killing itself. - watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY | O_NONBLOCK); - if(watchdogFifoFd < 0) { - if(errno == ENXIO) { - watchdogFifoFd = RETRY_FIFO_OPEN; - sif::info << "eive-watchdog not running. FIFO can not be opened" << std::endl; - } - else { - sif::error << "Opening pipe " << watchdog::FIFO_NAME << " write-only failed with " << - errno << ": " << strerror(errno) << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - } + if (not std::filesystem::exists(watchdog::FIFO_NAME)) { + // Still return RETURN_OK for now + sif::info << "Watchdog FIFO " << watchdog::FIFO_NAME << " does not exist, can't initiate" + << " watchdog" << std::endl; return HasReturnvaluesIF::RETURN_OK; + } + // Open FIFO write only and non-blocking to prevent SW from killing itself. + watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY | O_NONBLOCK); + if (watchdogFifoFd < 0) { + if (errno == ENXIO) { + watchdogFifoFd = RETRY_FIFO_OPEN; + sif::info << "eive-watchdog not running. FIFO can not be opened" << std::endl; + } else { + sif::error << "Opening pipe " << watchdog::FIFO_NAME << " write-only failed with " << errno + << ": " << strerror(errno) << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + } + return HasReturnvaluesIF::RETURN_OK; } void CoreController::initPrint() { #if OBSW_VERBOSE_LEVEL >= 1 - if(watchdogFifoFd > 0) { - sif::info << "Opened watchdog FIFO successfully.." << std::endl; - } + if (watchdogFifoFd > 0) { + sif::info << "Opened watchdog FIFO successfully.." << std::endl; + } #endif } ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t size) { - if(size < 1) { - return HasActionsIF::INVALID_PARAMETERS; - } - bool rebootSameBootCopy = data[0]; - bool protOpPerformed; - if(rebootSameBootCopy) { + if (size < 1) { + return HasActionsIF::INVALID_PARAMETERS; + } + bool rebootSameBootCopy = data[0]; + bool protOpPerformed; + if (rebootSameBootCopy) { #if OBSW_VERBOSE_LEVEL >= 1 - sif::info << "CoreController::actionPerformReboot: Rebooting on current image" << std::endl; + sif::info << "CoreController::actionPerformReboot: Rebooting on current image" << std::endl; #endif - // Attempt graceful shutdown by unmounting and switching off SD cards - SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_0); - SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_1); - // If any boot copies are unprotected - ReturnValue_t retval = setBootCopyProtection(Chip::SELF_CHIP, Copy::SELF_COPY, - true, protOpPerformed, false); - if(retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) { - sif::info << "Running slot was writeprotected before reboot" << std::endl; - } - int result = std::system("xsc_boot_copy -r"); - if(result != 0) { - utility::handleSystemError(result, "CoreController::executeAction"); - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasActionsIF::EXECUTION_FINISHED; + // Attempt graceful shutdown by unmounting and switching off SD cards + SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_0); + SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_1); + // If any boot copies are unprotected + ReturnValue_t retval = setBootCopyProtection(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, true, + protOpPerformed, false); + if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) { + sif::info << "Running slot was writeprotected before reboot" << std::endl; } - if(size < 3) { - return HasActionsIF::INVALID_PARAMETERS; - } -#if OBSW_VERBOSE_LEVEL >= 1 - sif::info << "CoreController::actionPerformReboot: Rebooting on " << - static_cast(data[1]) << " " << static_cast(data[2]) << std::endl; -#endif - - // Check that the target chip and copy is writeprotected first - generateChipStateFile(); - // If any boot copies are unprotected, protect them here - ReturnValue_t retval = setBootCopyProtection(static_cast(data[1]), - static_cast(data[2]), true, protOpPerformed, false); - if(retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) { - sif::info << "Target slot was writeprotected before reboot" << std::endl; - } - - // The second byte in data is the target chip, the third byte is the target copy - std::string cmdString = "xsc_boot_copy " + std::to_string(data[1]) + " " + - std::to_string(data[2]); - int result = std::system(cmdString.c_str()); - if(result != 0) { - utility::handleSystemError(result, "CoreController::executeAction"); - return HasReturnvaluesIF::RETURN_FAILED; + int result = std::system("xsc_boot_copy -r"); + if (result != 0) { + utility::handleSystemError(result, "CoreController::executeAction"); + return HasReturnvaluesIF::RETURN_FAILED; } return HasActionsIF::EXECUTION_FINISHED; + } + if (size < 3 or (data[1] > 1 or data[2] > 1)) { + return HasActionsIF::INVALID_PARAMETERS; + } +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "CoreController::actionPerformReboot: Rebooting on " << static_cast(data[1]) + << " " << static_cast(data[2]) << std::endl; +#endif + + // Check that the target chip and copy is writeprotected first + generateChipStateFile(); + // If any boot copies are unprotected, protect them here + auto tgtChip = static_cast(data[1]); + auto tgtCopy = static_cast(data[2]); + + ReturnValue_t retval = + setBootCopyProtection(static_cast(data[1]), static_cast(data[2]), true, + protOpPerformed, false); + if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) { + sif::info << "Target slot was writeprotected before reboot" << std::endl; + } + + switch (tgtChip) { + case (xsc::Chip::CHIP_0): { + switch (tgtCopy) { + case (xsc::Copy::COPY_0): { + xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_NOMINAL); + break; + } + case (xsc::Copy::COPY_1): { + xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_GOLD); + break; + } + default: { + break; + } + } + break; + } + case (xsc::Chip::CHIP_1): { + switch (tgtCopy) { + case (xsc::Copy::COPY_0): { + xsc_boot_copy(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_NOMINAL); + break; + } + case (xsc::Copy::COPY_1): { + xsc_boot_copy(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_GOLD); + break; + } + default: { + break; + } + } + break; + } + default: + break; + } + return HasReturnvaluesIF::RETURN_FAILED; } -CoreController::~CoreController() { -} +CoreController::~CoreController() {} void CoreController::determinePreferredSdCard() { - if(sdInfo.pref == sd::SdCard::NONE) { - ReturnValue_t result = sdcMan->getPreferredSdCard(sdInfo.pref); - if(result != HasReturnvaluesIF::RETURN_OK) { - if(result == scratch::KEY_NOT_FOUND) { - sif::warning << "CoreController::sdCardInit: " - "Preferred SD card not set. Setting to 0" << std::endl; - sdcMan->setPreferredSdCard(sd::SdCard::SLOT_0); - sdInfo.pref = sd::SdCard::SLOT_0; - } - else { - sif::warning << "CoreController::sdCardInit: Could not get preferred SD card" - "information from the scratch buffer" << std::endl; - } - } + if (sdInfo.pref == sd::SdCard::NONE) { + ReturnValue_t result = sdcMan->getPreferredSdCard(sdInfo.pref); + if (result != HasReturnvaluesIF::RETURN_OK) { + if (result == scratch::KEY_NOT_FOUND) { + sif::warning << "CoreController::sdCardInit: " + "Preferred SD card not set. Setting to 0" + << std::endl; + sdcMan->setPreferredSdCard(sd::SdCard::SLOT_0); + sdInfo.pref = sd::SdCard::SLOT_0; + } else { + sif::warning << "CoreController::sdCardInit: Could not get preferred SD card" + "information from the scratch buffer" + << std::endl; + } } + } } void CoreController::updateSdInfoOther() { - if(sdInfo.pref == sd::SdCard::SLOT_0) { - sdInfo.prefChar = "0"; - sdInfo.otherChar = "1"; - sdInfo.otherState = sdInfo.currentState.second; - sdInfo.prefState = sdInfo.currentState.first; - sdInfo.other = sd::SdCard::SLOT_1; + if (sdInfo.pref == sd::SdCard::SLOT_0) { + sdInfo.prefChar = "0"; + sdInfo.otherChar = "1"; + sdInfo.otherState = sdInfo.currentState.second; + sdInfo.prefState = sdInfo.currentState.first; + sdInfo.other = sd::SdCard::SLOT_1; - } - else if(sdInfo.pref == sd::SdCard::SLOT_1) { - sdInfo.prefChar = "1"; - sdInfo.otherChar = "0"; - sdInfo.otherState = sdInfo.currentState.first; - sdInfo.prefState = sdInfo.currentState.second; - sdInfo.other = sd::SdCard::SLOT_0; - } - else { - sif::warning << "CoreController::updateSdInfoOther: Invalid SD card passed" << std::endl; - } + } else if (sdInfo.pref == sd::SdCard::SLOT_1) { + sdInfo.prefChar = "1"; + sdInfo.otherChar = "0"; + sdInfo.otherState = sdInfo.currentState.first; + sdInfo.prefState = sdInfo.currentState.second; + sdInfo.other = sd::SdCard::SLOT_0; + } else { + sif::warning << "CoreController::updateSdInfoOther: Invalid SD card passed" << std::endl; + } } -bool CoreController::sdInitFinished() const { - return sdInfo.initFinished; -} +bool CoreController::sdInitFinished() const { return sdInfo.initFinished; } ReturnValue_t CoreController::generateChipStateFile() { - int result = std::system(CHIP_PROT_SCRIPT); - if(result != 0) { - utility::handleSystemError(result, "CoreController::generateChipStateFile"); - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; + int result = std::system(CHIP_PROT_SCRIPT); + if (result != 0) { + utility::handleSystemError(result, "CoreController::generateChipStateFile"); + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t CoreController::setBootCopyProtection(Chip targetChip, Copy targetCopy, - bool protect, bool& protOperationPerformed, bool updateProtFile) { - bool allChips = false; - bool allCopies = false; - bool selfChip = false; - bool selfCopy = false; - protOperationPerformed = false; +ReturnValue_t CoreController::setBootCopyProtection(xsc::Chip targetChip, xsc::Copy targetCopy, + bool protect, bool &protOperationPerformed, + bool updateProtFile) { + bool allChips = false; + bool allCopies = false; + bool selfChip = false; + bool selfCopy = false; + protOperationPerformed = false; - switch(targetChip) { - case(Chip::ALL_CHIP): { - allChips = true; - break; + switch (targetChip) { + case (xsc::Chip::ALL_CHIP): { + allChips = true; + break; } - case(Chip::NO_CHIP): { - return HasReturnvaluesIF::RETURN_OK; + case (xsc::Chip::NO_CHIP): { + return HasReturnvaluesIF::RETURN_OK; } - case(Chip::SELF_CHIP): { - selfChip = true; - targetChip = CURRENT_CHIP; - break; + case (xsc::Chip::SELF_CHIP): { + selfChip = true; + targetChip = CURRENT_CHIP; + break; } default: { - break; + break; } + } + switch (targetCopy) { + case (xsc::Copy::ALL_COPY): { + allCopies = true; + break; } - switch(targetCopy) { - case(Copy::ALL_COPY): { - allCopies = true; - break; + case (xsc::Copy::NO_COPY): { + return HasReturnvaluesIF::RETURN_OK; } - case(Copy::NO_COPY): { - return HasReturnvaluesIF::RETURN_OK; - } - case(Copy::SELF_COPY): { - selfCopy = true; - targetCopy = CURRENT_COPY; - break; + case (xsc::Copy::SELF_COPY): { + selfCopy = true; + targetCopy = CURRENT_COPY; + break; } default: { - break; - } + break; } + } - for(uint8_t arrIdx = 0; arrIdx < protArray.size(); arrIdx++) { - int result = handleBootCopyProtAtIndex(targetChip, targetCopy, protect, - protOperationPerformed, selfChip, selfCopy, allChips, allCopies, arrIdx); - if(result != 0) { - break; - } + for (uint8_t arrIdx = 0; arrIdx < protArray.size(); arrIdx++) { + int result = handleBootCopyProtAtIndex(targetChip, targetCopy, protect, protOperationPerformed, + selfChip, selfCopy, allChips, allCopies, arrIdx); + if (result != 0) { + break; } - if(protOperationPerformed and updateProtFile) { - updateProtInfo(); - } - return HasReturnvaluesIF::RETURN_OK; + } + if (protOperationPerformed and updateProtFile) { + updateProtInfo(); + } + return HasReturnvaluesIF::RETURN_OK; } -int CoreController::handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect, - bool &protOperationPerformed, bool selfChip, bool selfCopy, bool allChips, - bool allCopies, uint8_t arrIdx) { - bool currentProt = protArray[arrIdx]; - std::ostringstream oss; - bool performOp = false; - if(protect == currentProt) { - return 0; - } - if(protOperationPerformed) { - if((selfChip and selfCopy) or (not allCopies and not allChips)) { - // No need to continue, only one operation was requested - return 1; - } - } - Chip currentChip; - Copy currentCopy; - oss << "writeprotect "; - if(arrIdx == 0 or arrIdx == 1) { - oss << "0 "; - currentChip = Chip::CHIP_0; - } - else { - oss << "1 "; - currentChip = Chip::CHIP_1; - } - if(arrIdx == 0 or arrIdx == 2) { - oss << "0 "; - currentCopy = Copy::COPY_0; - } - else { - oss << "1 "; - currentCopy = Copy::COPY_1; - } - if(protect) { - oss << "1"; - } - else { - oss << "0"; - } - - int result = 0; - if(allChips and allCopies) { - performOp = true; - } - else if(allChips) { - if((selfCopy and CURRENT_COPY == targetCopy) or - (currentCopy == targetCopy)) { - performOp = true; - } - } - else if(allCopies) { - if((selfChip and CURRENT_COPY == targetCopy) or - (currentChip == targetChip)) { - performOp = true; - } - } - else if(selfChip and (currentChip == targetChip)) { - if(selfCopy) { - if(currentCopy == targetCopy) { - performOp = true; - } - } - else { - performOp = true; - } - - } - else if(selfCopy and (currentCopy == targetCopy)) { - if(selfChip) { - if(currentChip == targetChip) { - performOp = true; - } - } - else { - performOp = true; - } - } - else if((targetChip == currentChip) and (targetCopy == currentCopy)) { - performOp = true; - } - if(result != 0) { - utility::handleSystemError(result, "CoreController::checkAndSetBootCopyProtection"); - } - if(performOp) { - // TODO: Lock operation take a long time. Use command executor? That would require a - // new state machine.. - protOperationPerformed = true; - sif::info << "Executing command: " << oss.str() << std::endl; - result = std::system(oss.str().c_str()); - } +int CoreController::handleBootCopyProtAtIndex(xsc::Chip targetChip, xsc::Copy targetCopy, + bool protect, bool &protOperationPerformed, + bool selfChip, bool selfCopy, bool allChips, + bool allCopies, uint8_t arrIdx) { + bool currentProt = protArray[arrIdx]; + std::ostringstream oss; + bool performOp = false; + if (protect == currentProt) { return 0; + } + if (protOperationPerformed) { + if ((selfChip and selfCopy) or (not allCopies and not allChips)) { + // No need to continue, only one operation was requested + return 1; + } + } + xsc::Chip currentChip; + xsc::Copy currentCopy; + oss << "writeprotect "; + if (arrIdx == 0 or arrIdx == 1) { + oss << "0 "; + currentChip = xsc::Chip::CHIP_0; + } else { + oss << "1 "; + currentChip = xsc::Chip::CHIP_1; + } + if (arrIdx == 0 or arrIdx == 2) { + oss << "0 "; + currentCopy = xsc::Copy::COPY_0; + } else { + oss << "1 "; + currentCopy = xsc::Copy::COPY_1; + } + if (protect) { + oss << "1"; + } else { + oss << "0"; + } + + int result = 0; + if (allChips and allCopies) { + performOp = true; + } else if (allChips) { + if ((selfCopy and CURRENT_COPY == targetCopy) or (currentCopy == targetCopy)) { + performOp = true; + } + } else if (allCopies) { + if ((selfChip and CURRENT_COPY == targetCopy) or (currentChip == targetChip)) { + performOp = true; + } + } else if (selfChip and (currentChip == targetChip)) { + if (selfCopy) { + if (currentCopy == targetCopy) { + performOp = true; + } + } else { + performOp = true; + } + + } else if (selfCopy and (currentCopy == targetCopy)) { + if (selfChip) { + if (currentChip == targetChip) { + performOp = true; + } + } else { + performOp = true; + } + } else if ((targetChip == currentChip) and (targetCopy == currentCopy)) { + performOp = true; + } + if (result != 0) { + utility::handleSystemError(result, "CoreController::checkAndSetBootCopyProtection"); + } + if (performOp) { + // TODO: Lock operation take a long time. Use command executor? That would require a + // new state machine.. + protOperationPerformed = true; + sif::info << "Executing command: " << oss.str() << std::endl; + result = std::system(oss.str().c_str()); + } + return 0; } ReturnValue_t CoreController::updateProtInfo(bool regenerateChipStateFile) { - using namespace std; - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - if(regenerateChipStateFile) { - result = generateChipStateFile(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::updateProtInfo: Generating chip state file failed" << - std::endl; - return result; - } + using namespace std; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if (regenerateChipStateFile) { + result = generateChipStateFile(); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::updateProtInfo: Generating chip state file failed" + << std::endl; + return result; } - if(not filesystem::exists(CHIP_STATE_FILE)) { - return HasReturnvaluesIF::RETURN_FAILED; + } + if (not filesystem::exists(CHIP_STATE_FILE)) { + return HasReturnvaluesIF::RETURN_FAILED; + } + ifstream chipStateFile(CHIP_STATE_FILE); + if (not chipStateFile.good()) { + return HasReturnvaluesIF::RETURN_FAILED; + } + string nextLine; + uint8_t lineCounter = 0; + string word; + while (getline(chipStateFile, nextLine)) { + ReturnValue_t result = handleProtInfoUpdateLine(nextLine); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::updateProtInfo: Protection info update failed!" << std::endl; + return result; } - ifstream chipStateFile(CHIP_STATE_FILE); - if(not chipStateFile.good()) { - return HasReturnvaluesIF::RETURN_FAILED; + ++lineCounter; + if (lineCounter > 4) { + sif::warning << "CoreController::checkAndProtectBootCopy: " + "Line counter larger than 4" + << std::endl; } - string nextLine; - uint8_t lineCounter = 0; - string word; - while(getline(chipStateFile, nextLine)) { - ReturnValue_t result = handleProtInfoUpdateLine(nextLine); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::updateProtInfo: Protection info update failed!" << - std::endl; - return result; - } - ++lineCounter; - if(lineCounter > 4) { - sif::warning << "CoreController::checkAndProtectBootCopy: " - "Line counter larger than 4" << std::endl; - } - } - return HasReturnvaluesIF::RETURN_OK; + } + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t CoreController::handleProtInfoUpdateLine(std::string nextLine) { - using namespace std; - string word; - uint8_t wordIdx = 0; - uint8_t arrayIdx = 0; - istringstream iss(nextLine); - Chip currentChip = Chip::CHIP_0; - Copy currentCopy = Copy::COPY_0; - while(iss >> word) { - if(wordIdx == 1) { - currentChip = static_cast(stoi(word)); - } - if(wordIdx == 3) { - currentCopy = static_cast(stoi(word)); - } - - if(wordIdx == 3) { - if(currentChip == Chip::CHIP_0) { - if(currentCopy == Copy::COPY_0) { - arrayIdx = 0; - } - else if(currentCopy == Copy::COPY_1) { - arrayIdx = 1; - } - } - - else if(currentChip == Chip::CHIP_1) { - if(currentCopy == Copy::COPY_0) { - arrayIdx = 2; - } - else if(currentCopy == Copy::COPY_1) { - arrayIdx = 3; - } - } - } - if(wordIdx == 5) { - if(word == "unlocked.") { - protArray[arrayIdx] = false; - } - else { - protArray[arrayIdx] = true; - } - } - wordIdx++; + using namespace std; + string word; + uint8_t wordIdx = 0; + uint8_t arrayIdx = 0; + istringstream iss(nextLine); + xsc::Chip currentChip = xsc::Chip::CHIP_0; + xsc::Copy currentCopy = xsc::Copy::COPY_0; + while (iss >> word) { + if (wordIdx == 1) { + currentChip = static_cast(stoi(word)); } - return HasReturnvaluesIF::RETURN_OK; + if (wordIdx == 3) { + currentCopy = static_cast(stoi(word)); + } + + if (wordIdx == 3) { + if (currentChip == xsc::Chip::CHIP_0) { + if (currentCopy == xsc::Copy::COPY_0) { + arrayIdx = 0; + } else if (currentCopy == xsc::Copy::COPY_1) { + arrayIdx = 1; + } + } + + else if (currentChip == xsc::Chip::CHIP_1) { + if (currentCopy == xsc::Copy::COPY_0) { + arrayIdx = 2; + } else if (currentCopy == xsc::Copy::COPY_1) { + arrayIdx = 3; + } + } + } + if (wordIdx == 5) { + if (word == "unlocked.") { + protArray[arrayIdx] = false; + } else { + protArray[arrayIdx] = true; + } + } + wordIdx++; + } + return HasReturnvaluesIF::RETURN_OK; } void CoreController::performWatchdogControlOperation() { - // Only perform each fifth iteration - if(watchdogFifoFd != 0 and opDivider.checkAndIncrement()) { - if(watchdogFifoFd == RETRY_FIFO_OPEN) { - // Open FIFO write only and non-blocking - watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY | O_NONBLOCK); - if(watchdogFifoFd < 0) { - if(errno == ENXIO) { - watchdogFifoFd = RETRY_FIFO_OPEN; - // No printout for now, would be spam - return; - } - else { - sif::error << "Opening pipe " << watchdog::FIFO_NAME << - " write-only failed with " << errno << ": " << - strerror(errno) << std::endl; - return; - } - } - sif::info << "Opened " << watchdog::FIFO_NAME << " successfully" << std::endl; - } - else if(watchdogFifoFd > 0) { - // Write to OBSW watchdog FIFO here - const char writeChar = 'a'; - ssize_t writtenBytes = write(watchdogFifoFd, &writeChar, 1); - if(writtenBytes < 0) { - sif::error << "Errors writing to watchdog FIFO, code " << errno << ": " << - strerror(errno) << std::endl; - } + // Only perform each fifth iteration + if (watchdogFifoFd != 0 and opDivider.checkAndIncrement()) { + if (watchdogFifoFd == RETRY_FIFO_OPEN) { + // Open FIFO write only and non-blocking + watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY | O_NONBLOCK); + if (watchdogFifoFd < 0) { + if (errno == ENXIO) { + watchdogFifoFd = RETRY_FIFO_OPEN; + // No printout for now, would be spam + return; + } else { + sif::error << "Opening pipe " << watchdog::FIFO_NAME << " write-only failed with " + << errno << ": " << strerror(errno) << std::endl; + return; } + } + sif::info << "Opened " << watchdog::FIFO_NAME << " successfully" << std::endl; + } else if (watchdogFifoFd > 0) { + // Write to OBSW watchdog FIFO here + const char writeChar = 'a'; + ssize_t writtenBytes = write(watchdogFifoFd, &writeChar, 1); + if (writtenBytes < 0) { + sif::error << "Errors writing to watchdog FIFO, code " << errno << ": " << strerror(errno) + << std::endl; + } } - + } +} + +void CoreController::performMountedSdCardOperations() { + if (doPerformMountedSdCardOps) { + bool sdCardMounted = false; + sdCardMounted = sdcMan->isSdCardMounted(sdInfo.pref); + if (sdCardMounted) { + std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + "/" + CONF_FOLDER; + if (not std::filesystem::exists(path)) { + std::filesystem::create_directory(path); + } + initVersionFile(); + performRebootFileHandling(false); + doPerformMountedSdCardOps = false; + } + } +} + +void CoreController::performRebootFileHandling(bool recreateFile) { + using namespace std; + std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + if (not std::filesystem::exists(path) or recreateFile) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "CoreController::performRebootFileHandling: Recreating reboot file" << std::endl; +#endif + rebootFile.enabled = true; + rebootFile.img00Cnt = 0; + rebootFile.img01Cnt = 0; + rebootFile.img10Cnt = 0; + rebootFile.img11Cnt = 0; + rebootFile.lastChip = xsc::Chip::CHIP_0; + rebootFile.lastCopy = xsc::Copy::COPY_0; + rebootFile.img00Lock = false; + rebootFile.img01Lock = false; + rebootFile.img10Lock = false; + rebootFile.img11Lock = false; + rebootFile.mechanismNextChip = xsc::Chip::NO_CHIP; + rebootFile.mechanismNextCopy = xsc::Copy::NO_COPY; + rebootFile.bootFlag = false; + rewriteRebootFile(rebootFile); + } else { + if (not parseRebootFile(path, rebootFile)) { + performRebootFileHandling(true); + } + } + + if (CURRENT_CHIP == xsc::CHIP_0) { + if (CURRENT_COPY == xsc::COPY_0) { + rebootFile.img00Cnt++; + } else { + rebootFile.img01Cnt++; + } + } else { + if (CURRENT_COPY == xsc::COPY_0) { + rebootFile.img10Cnt++; + } else { + rebootFile.img11Cnt++; + } + } + + if (rebootFile.bootFlag) { + // Trigger event to inform ground that a reboot was triggered + uint32_t p1 = rebootFile.lastChip << 16 | rebootFile.lastCopy; + uint32_t p2 = rebootFile.img00Cnt << 24 | rebootFile.img01Cnt << 16 | rebootFile.img10Cnt << 8 | + rebootFile.img11Cnt; + triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, p2); + // Clear the boot flag + rebootFile.bootFlag = false; + } + + if (rebootFile.mechanismNextChip != xsc::NO_CHIP and + rebootFile.mechanismNextCopy != xsc::NO_COPY) { + if (CURRENT_CHIP != rebootFile.mechanismNextChip or + CURRENT_COPY != rebootFile.mechanismNextCopy) { + std::string infoString = std::to_string(rebootFile.mechanismNextChip) + " " + + std::to_string(rebootFile.mechanismNextCopy); + sif::warning << "CoreController::performRebootFileHandling: Expected to be on image " + << infoString << " but currently on other image. Locking " << infoString + << std::endl; + // Firmware or other component might be corrupt and we are on another image then the target + // image specified by the mechanism. We can't really trust the target image anymore. + // Lock it for now + if (rebootFile.mechanismNextChip == xsc::CHIP_0) { + if (rebootFile.mechanismNextCopy == xsc::COPY_0) { + rebootFile.img00Lock = true; + } else { + rebootFile.img01Lock = true; + } + } else { + if (rebootFile.mechanismNextCopy == xsc::COPY_0) { + rebootFile.img10Lock = true; + } else { + rebootFile.img11Lock = true; + } + } + } + } + + rebootFile.lastChip = CURRENT_CHIP; + rebootFile.lastCopy = CURRENT_COPY; + // Only reboot if the reboot functionality is enabled. + // The handler will still increment the boot counts + if (rebootFile.enabled and (*rebootFile.relevantBootCnt >= rebootFile.maxCount)) { + // Reboot to other image + bool doReboot = false; + xsc::Chip tgtChip = xsc::NO_CHIP; + xsc::Copy tgtCopy = xsc::NO_COPY; + determineAndExecuteReboot(rebootFile, doReboot, tgtChip, tgtCopy); + if (doReboot) { + rebootFile.bootFlag = true; +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "Boot counter for image " << CURRENT_CHIP << " " << CURRENT_COPY + << " too high. Rebooting to " << tgtChip << " " << tgtCopy << std::endl; +#endif + rebootFile.mechanismNextChip = tgtChip; + rebootFile.mechanismNextCopy = tgtCopy; + rewriteRebootFile(rebootFile); + xsc_boot_copy(static_cast(tgtChip), + static_cast(tgtCopy)); + } + } else { + rebootFile.mechanismNextChip = xsc::NO_CHIP; + rebootFile.mechanismNextCopy = xsc::NO_COPY; + } + rewriteRebootFile(rebootFile); +} + +void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot, + xsc::Chip &tgtChip, xsc::Copy &tgtCopy) { + tgtChip = xsc::CHIP_0; + tgtCopy = xsc::COPY_0; + needsReboot = false; + if ((CURRENT_CHIP == xsc::CHIP_0) and (CURRENT_COPY == xsc::COPY_0) and + (rf.img00Cnt >= rf.maxCount)) { + needsReboot = true; + if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) { + tgtCopy = xsc::COPY_1; + return; + } + if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) { + tgtChip = xsc::CHIP_1; + return; + } + if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) { + tgtChip = xsc::CHIP_1; + tgtCopy = xsc::COPY_1; + return; + } + // Can't really do much here. Stay on image + sif::warning + << "All reboot counts too high or all fallback images locked, already on fallback image" + << std::endl; + needsReboot = false; + return; + } + if ((CURRENT_CHIP == xsc::CHIP_0) and (CURRENT_COPY == xsc::COPY_1) and + (rf.img01Cnt >= rf.maxCount)) { + needsReboot = true; + if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) { + // Reboot on fallback image + return; + } + if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) { + tgtChip = xsc::CHIP_1; + return; + } + if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) { + tgtChip = xsc::CHIP_1; + tgtCopy = xsc::COPY_1; + } + if (rf.img00Lock) { + needsReboot = false; + } + // Reboot to fallback image + } + if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_0) and + (rf.img10Cnt >= rf.maxCount)) { + needsReboot = true; + if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) { + tgtChip = xsc::CHIP_1; + tgtCopy = xsc::COPY_1; + return; + } + if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) { + return; + } + if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) { + tgtCopy = xsc::COPY_1; + return; + } + if (rf.img00Lock) { + needsReboot = false; + } + // Reboot to fallback image + } + if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_1) and + (rf.img11Cnt >= rf.maxCount)) { + needsReboot = true; + if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) { + tgtChip = xsc::CHIP_1; + return; + } + if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) { + return; + } + if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) { + tgtCopy = xsc::COPY_1; + return; + } + if (rf.img00Lock) { + needsReboot = false; + } + // Reboot to fallback image + } +} + +bool CoreController::parseRebootFile(std::string path, RebootFile &rf) { + using namespace std; + std::string selfMatch; + if (CURRENT_CHIP == xsc::CHIP_0) { + if (CURRENT_COPY == xsc::COPY_0) { + selfMatch = "00"; + } else { + selfMatch = "01"; + } + } else { + if (CURRENT_COPY == xsc::COPY_0) { + selfMatch = "10"; + } else { + selfMatch = "11"; + } + } + ifstream file(path); + string word; + string line; + uint8_t lineIdx = 0; + while (std::getline(file, line)) { + istringstream iss(line); + switch (lineIdx) { + case 0: { + iss >> word; + if (word.find("on:") == string::npos) { + // invalid file + return false; + } + iss >> rf.enabled; + break; + } + case 1: { + iss >> word; + if (word.find("maxcnt:") == string::npos) { + return false; + } + iss >> rf.maxCount; + break; + } + case 2: { + iss >> word; + if (word.find("img00:") == string::npos) { + return false; + } + iss >> rf.img00Cnt; + if (word.find(selfMatch) != string::npos) { + rf.relevantBootCnt = &rf.img00Cnt; + } + break; + } + case 3: { + iss >> word; + if (word.find("img01:") == string::npos) { + return false; + } + iss >> rf.img01Cnt; + if (word.find(selfMatch) != string::npos) { + rf.relevantBootCnt = &rf.img01Cnt; + } + break; + } + case 4: { + iss >> word; + if (word.find("img10:") == string::npos) { + return false; + } + iss >> rf.img10Cnt; + if (word.find(selfMatch) != string::npos) { + rf.relevantBootCnt = &rf.img10Cnt; + } + break; + } + case 5: { + iss >> word; + if (word.find("img11:") == string::npos) { + return false; + } + iss >> rf.img11Cnt; + if (word.find(selfMatch) != string::npos) { + rf.relevantBootCnt = &rf.img11Cnt; + } + break; + } + case 6: { + iss >> word; + if (word.find("img00lock:") == string::npos) { + return false; + } + iss >> rf.img00Lock; + break; + } + case 7: { + iss >> word; + if (word.find("img01lock:") == string::npos) { + return false; + } + iss >> rf.img01Lock; + break; + } + case 8: { + iss >> word; + if (word.find("img10lock:") == string::npos) { + return false; + } + iss >> rf.img10Lock; + break; + } + case 9: { + iss >> word; + if (word.find("img11lock:") == string::npos) { + return false; + } + iss >> rf.img11Lock; + break; + } + case 10: { + iss >> word; + if (word.find("bootflag:") == string::npos) { + return false; + } + iss >> rf.bootFlag; + break; + } + case 11: { + iss >> word; + int copyRaw = 0; + int chipRaw = 0; + if (word.find("last:") == string::npos) { + return false; + } + iss >> chipRaw; + if (iss.fail()) { + return false; + } + iss >> copyRaw; + if (iss.fail()) { + return false; + } + + if (chipRaw > 1 or copyRaw > 1) { + return false; + } + rf.lastChip = static_cast(chipRaw); + rf.lastCopy = static_cast(copyRaw); + break; + } + case 12: { + iss >> word; + int copyRaw = 0; + int chipRaw = 0; + if (word.find("next:") == string::npos) { + return false; + } + iss >> chipRaw; + if (iss.fail()) { + return false; + } + iss >> copyRaw; + if (iss.fail()) { + return false; + } + + if (chipRaw > 2 or copyRaw > 2) { + return false; + } + rf.mechanismNextChip = static_cast(chipRaw); + rf.mechanismNextCopy = static_cast(copyRaw); + break; + } + } + if (iss.fail()) { + return false; + } + lineIdx++; + } + if (lineIdx < 12) { + return false; + } + return true; +} + +void CoreController::resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy) { + std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + // Disable the reboot file mechanism + parseRebootFile(path, rebootFile); + if (tgtChip == xsc::ALL_CHIP and tgtCopy == xsc::ALL_COPY) { + rebootFile.img00Cnt = 0; + rebootFile.img01Cnt = 0; + rebootFile.img10Cnt = 0; + rebootFile.img11Cnt = 0; + } else { + if (tgtChip == xsc::CHIP_0) { + if (tgtCopy == xsc::COPY_0) { + rebootFile.img00Cnt = 0; + } else { + rebootFile.img01Cnt = 0; + } + } else { + if (tgtCopy == xsc::COPY_0) { + rebootFile.img10Cnt = 0; + } else { + rebootFile.img11Cnt = 0; + } + } + } + rewriteRebootFile(rebootFile); +} + +void CoreController::rewriteRebootFile(RebootFile file) { + std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + std::ofstream rebootFile(path); + if (rebootFile.is_open()) { + // Initiate reboot file first. Reboot handling will be on on initialization + rebootFile << "on: " << file.enabled << "\nmaxcnt: " << file.maxCount + << "\nimg00: " << file.img00Cnt << "\nimg01: " << file.img01Cnt + << "\nimg10: " << file.img10Cnt << "\nimg11: " << file.img11Cnt + << "\nimg00lock: " << file.img00Lock << "\nimg01lock: " << file.img01Lock + << "\nimg10lock: " << file.img10Lock << "\nimg11lock: " << file.img11Lock + << "\nbootflag: " << file.bootFlag << "\nlast: " << static_cast(file.lastChip) + << " " << static_cast(file.lastCopy) + << "\nnext: " << static_cast(file.mechanismNextChip) << " " + << static_cast(file.mechanismNextCopy) << "\n"; + } +} + +void CoreController::setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy) { + std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + // Disable the reboot file mechanism + parseRebootFile(path, rebootFile); + if (tgtChip == xsc::CHIP_0) { + if (tgtCopy == xsc::COPY_0) { + rebootFile.img00Lock = lock; + } else { + rebootFile.img01Lock = lock; + } + } else { + if (tgtCopy == xsc::COPY_0) { + rebootFile.img10Lock = lock; + } else { + rebootFile.img11Lock = lock; + } + } + rewriteRebootFile(rebootFile); +} + +void CoreController::readHkData() { + ReturnValue_t result = RETURN_OK; + result = hkSet.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return; + } + Xadc xadc; + result = xadc.getTemperature(hkSet.temperature.value); + if (result != RETURN_OK) { + hkSet.temperature.setValid(false); + } else { + hkSet.temperature.setValid(true); + } + result = xadc.getVccPint(hkSet.psVoltage.value); + if (result != RETURN_OK) { + hkSet.psVoltage.setValid(false); + } else { + hkSet.psVoltage.setValid(true); + } + result = xadc.getVccInt(hkSet.plVoltage.value); + if (result != RETURN_OK) { + hkSet.plVoltage.setValid(false); + } else { + hkSet.plVoltage.setValid(true); + } +#if OBSW_PRINT_CORE_HK == 1 + hkSet.printSet(); +#endif /* OBSW_PRINT_CORE_HK == 1 */ + result = hkSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return; + } } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 74702441..e31378ef 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -2,183 +2,230 @@ #define BSP_Q7S_CORE_CORECONTROLLER_H_ #include -#include "fsfw/controller/ExtendedControllerBase.h" +#include + +#include + +#include "CoreDefinitions.h" #include "bsp_q7s/memory/SdCardManager.h" - #include "events/subsystemIdRanges.h" - +#include "fsfw/controller/ExtendedControllerBase.h" class Timer; class SdCardManager; -class CoreController: public ExtendedControllerBase { -public: - enum Chip: uint8_t { - CHIP_0, - CHIP_1, - NO_CHIP, - SELF_CHIP, - ALL_CHIP - }; +namespace xsc { - enum Copy: uint8_t { - COPY_0, - COPY_1, - NO_COPY, - SELF_COPY, - ALL_COPY - }; +enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP }; +enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY }; - static constexpr char CHIP_PROT_SCRIPT[] = "/home/root/scripts/get-chip-prot-status.sh"; - static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt"; - static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt"; - static constexpr char VERSION_FILE[] = "/conf/sd_status"; +} // namespace xsc - static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0; - static constexpr ActionId_t REBOOT_OBC = 32; - static constexpr ActionId_t MOUNT_OTHER_COPY = 33; +struct RebootFile { + static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10; + bool enabled = true; + size_t maxCount = DEFAULT_MAX_BOOT_CNT; + uint32_t img00Cnt = 0; + uint32_t img01Cnt = 0; + uint32_t img10Cnt = 0; + uint32_t img11Cnt = 0; + bool img00Lock = false; + bool img01Lock = false; + bool img10Lock = false; + bool img11Lock = false; + uint32_t* relevantBootCnt = &img00Cnt; + bool bootFlag = false; + xsc::Chip lastChip = xsc::Chip::CHIP_0; + xsc::Copy lastCopy = xsc::Copy::COPY_0; + xsc::Chip mechanismNextChip = xsc::Chip::NO_CHIP; + xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY; +}; - static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE; +class CoreController : public ExtendedControllerBase { + public: + static xsc::Chip CURRENT_CHIP; + static xsc::Copy CURRENT_COPY; - static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); + static constexpr char CHIP_PROT_SCRIPT[] = "/home/root/scripts/get-chip-prot-status.sh"; + static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt"; + static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt"; + static constexpr char CONF_FOLDER[] = "conf"; + static constexpr char VERSION_FILE_NAME[] = "version.txt"; + static constexpr char REBOOT_FILE_NAME[] = "reboot.txt"; + const std::string VERSION_FILE = + "/" + std::string(CONF_FOLDER) + "/" + std::string(VERSION_FILE_NAME); + const std::string REBOOT_FILE = + "/" + std::string(CONF_FOLDER) + "/" + std::string(REBOOT_FILE_NAME); + static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0; + static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5; + static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6; + static constexpr ActionId_t SWITCH_IMG_LOCK = 7; + static constexpr ActionId_t SET_MAX_REBOOT_CNT = 8; - CoreController(object_id_t objectId); - virtual~ CoreController(); + static constexpr ActionId_t REBOOT_OBC = 32; + static constexpr ActionId_t MOUNT_OTHER_COPY = 33; - ReturnValue_t initialize() override; + static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE; - ReturnValue_t initializeAfterTaskCreation() override; + static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); + //! [EXPORT] : [COMMENT] Software reboot occured. Can also be a systemd reboot. + //! P1: Current Chip, P2: Current Copy + static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::MEDIUM); + //! [EXPORT] : [COMMENT] The reboot mechanism was triggered. + //! P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, + //! P2: Each byte is the respective reboot count for the slots + static constexpr Event REBOOT_MECHANISM_TRIGGERED = + event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM); + //! Trying to find a way how to determine that the reboot came from ProASIC3 or PCDU.. + static constexpr Event REBOOT_HW = event::makeEvent(SUBSYSTEM_ID, 3, severity::MEDIUM); - ReturnValue_t executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t *data, size_t size) override; + CoreController(object_id_t objectId); + virtual ~CoreController(); - ReturnValue_t handleCommandMessage(CommandMessage *message) override; - void performControlOperation() override; + ReturnValue_t initialize() override; - /** - * Generate a file containing the chip lock/unlock states inside /tmp/chip_prot_status.txt - * @return - */ - static ReturnValue_t generateChipStateFile(); - static ReturnValue_t incrementAllocationFailureCount(); - static void getCurrentBootCopy(Chip& chip, Copy& copy); + ReturnValue_t initializeAfterTaskCreation() override; - ReturnValue_t updateProtInfo(bool regenerateChipStateFile = true); + ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) override; - /** - * Checks whether the target chip and copy are write protected and protect set them to a target - * state where applicable. - * @param targetChip - * @param targetCopy - * @param protect Target state - * @param protOperationPerformed [out] Can be used to determine whether any operation - * was performed - * @param updateProtFile Specify whether the protection info file is updated - * @return - */ - ReturnValue_t setBootCopyProtection(Chip targetChip, Copy targetCopy, - bool protect, bool& protOperationPerformed, bool updateProtFile = true); + ReturnValue_t handleCommandMessage(CommandMessage* message) override; + void performControlOperation() override; - bool sdInitFinished() const; + /** + * Generate a file containing the chip lock/unlock states inside /tmp/chip_prot_status.txt + * @return + */ + static ReturnValue_t generateChipStateFile(); + static ReturnValue_t incrementAllocationFailureCount(); + static void getCurrentBootCopy(xsc::Chip& chip, xsc::Copy& copy); -private: - static Chip CURRENT_CHIP; - static Copy CURRENT_COPY; + ReturnValue_t updateProtInfo(bool regenerateChipStateFile = true); - // Designated value for rechecking FIFO open - static constexpr int RETRY_FIFO_OPEN = -2; - int watchdogFifoFd = 0; + /** + * Checks whether the target chip and copy are write protected and protect set them to a target + * state where applicable. + * @param targetChip + * @param targetCopy + * @param protect Target state + * @param protOperationPerformed [out] Can be used to determine whether any operation + * was performed + * @param updateProtFile Specify whether the protection info file is updated + * @return + */ + ReturnValue_t setBootCopyProtection(xsc::Chip targetChip, xsc::Copy targetCopy, bool protect, + bool& protOperationPerformed, bool updateProtFile = true); - // States for SD state machine, which is used in non-blocking mode - enum class SdStates { - NONE, - START, - GET_INFO, - SET_STATE_SELF, - MOUNT_SELF, - // Determine operations for other SD card, depending on redundancy configuration - DETERMINE_OTHER, - SET_STATE_OTHER, - // Mount or unmount other - MOUNT_UNMOUNT_OTHER, - // Skip period because the shell command used to generate the info file sometimes is - // missing the last performed operation if executed too early - SKIP_CYCLE_BEFORE_INFO_UPDATE, - UPDATE_INFO, - // SD initialization done - IDLE, - // Used if SD switches or mount commands are issued via telecommand - SET_STATE_FROM_COMMAND, - }; - static constexpr bool BLOCKING_SD_INIT = false; + bool sdInitFinished() const; - SdCardManager* sdcMan = nullptr; + private: + static constexpr MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING; + static constexpr uint32_t MUTEX_TIMEOUT = 20; + // Designated value for rechecking FIFO open + static constexpr int RETRY_FIFO_OPEN = -2; + int watchdogFifoFd = 0; - struct SdInfo { - sd::SdCard pref = sd::SdCard::NONE; - sd::SdState prefState = sd::SdState::OFF; - sd::SdCard other = sd::SdCard::NONE; - sd::SdState otherState = sd::SdState::OFF; - std::string prefChar = "0"; - std::string otherChar = "1"; - SdStates state = SdStates::START; - // Used to track whether a command was executed - bool commandExecuted = true; - bool initFinished = false; - SdCardManager::SdStatePair currentState; - uint16_t cycleCount = 0; - // These two flags are related to external commanding - bool commandIssued = false; - bool commandFinished = false; - sd::SdState currentlyCommandedState = sd::SdState::OFF; - sd::SdCard commandedCard = sd::SdCard::NONE; - sd::SdState commandedState = sd::SdState::OFF; - }; - SdInfo sdInfo; + // States for SD state machine, which is used in non-blocking mode + enum class SdStates { + NONE, + START, + GET_INFO, + SET_STATE_SELF, + MOUNT_SELF, + // Determine operations for other SD card, depending on redundancy configuration + DETERMINE_OTHER, + SET_STATE_OTHER, + // Mount or unmount other + MOUNT_UNMOUNT_OTHER, + // Skip period because the shell command used to generate the info file sometimes is + // missing the last performed operation if executed too early + SKIP_CYCLE_BEFORE_INFO_UPDATE, + UPDATE_INFO, + // SD initialization done + IDLE, + // Used if SD switches or mount commands are issued via telecommand + SET_STATE_FROM_COMMAND, + }; + static constexpr bool BLOCKING_SD_INIT = false; - /** - * Index 0: Chip 0 Copy 0 - * Index 1: Chip 0 Copy 1 - * Index 2: Chip 1 Copy 0 - * Index 3: Chip 1 Copy 1 - */ - std::array protArray; - PeriodicOperationDivider opDivider; + SdCardManager* sdcMan = nullptr; - ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) override; - LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; - ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t *msToReachTheMode); + struct SdInfo { + sd::SdCard pref = sd::SdCard::NONE; + sd::SdState prefState = sd::SdState::OFF; + sd::SdCard other = sd::SdCard::NONE; + sd::SdState otherState = sd::SdState::OFF; + std::string prefChar = "0"; + std::string otherChar = "1"; + SdStates state = SdStates::START; + // Used to track whether a command was executed + bool commandExecuted = true; + bool initFinished = false; + SdCardManager::SdStatePair currentState; + uint16_t cycleCount = 0; + // These two flags are related to external commanding + bool commandIssued = false; + bool commandFinished = false; + sd::SdState currentlyCommandedState = sd::SdState::OFF; + sd::SdCard commandedCard = sd::SdCard::NONE; + sd::SdState commandedState = sd::SdState::OFF; + } sdInfo; + RebootFile rebootFile = {}; + bool doPerformMountedSdCardOps = true; - ReturnValue_t initVersionFile(); - ReturnValue_t initBootCopy(); - ReturnValue_t initWatchdogFifo(); - ReturnValue_t initSdCardBlocking(); - void initPrint(); + /** + * Index 0: Chip 0 Copy 0 + * Index 1: Chip 0 Copy 1 + * Index 2: Chip 1 Copy 0 + * Index 3: Chip 1 Copy 1 + */ + std::array protArray; + PeriodicOperationDivider opDivider; - ReturnValue_t sdStateMachine(); - void updateSdInfoOther(); - ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar, - bool printOutput = true); - ReturnValue_t sdColdRedundantBlockingInit(); - void currentStateSetter(sd::SdCard sdCard, sd::SdState newState); - void determinePreferredSdCard(); - void executeNextExternalSdCommand(); - void checkExternalSdCommandStatus(); + core::HkSet hkSet; - ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy, - const uint8_t *data, size_t size); - ReturnValue_t actionPerformReboot(const uint8_t *data, size_t size); + ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; + LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; + ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t* msToReachTheMode); + void performMountedSdCardOperations(); + ReturnValue_t initVersionFile(); + ReturnValue_t initBootCopy(); + ReturnValue_t initWatchdogFifo(); + ReturnValue_t initSdCardBlocking(); + void initPrint(); - void performWatchdogControlOperation(); + ReturnValue_t sdStateMachine(); + void updateSdInfoOther(); + ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar, + bool printOutput = true); + ReturnValue_t sdColdRedundantBlockingInit(); - ReturnValue_t handleProtInfoUpdateLine(std::string nextLine); - int handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect, - bool &protOperationPerformed, bool selfChip, bool selfCopy, bool allChips, - bool allCopies, uint8_t arrIdx); + void currentStateSetter(sd::SdCard sdCard, sd::SdState newState); + void determinePreferredSdCard(); + void executeNextExternalSdCommand(); + void checkExternalSdCommandStatus(); + void performRebootFileHandling(bool recreateFile); + + ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size); + ReturnValue_t actionPerformReboot(const uint8_t* data, size_t size); + + void performWatchdogControlOperation(); + + ReturnValue_t handleProtInfoUpdateLine(std::string nextLine); + int handleBootCopyProtAtIndex(xsc::Chip targetChip, xsc::Copy targetCopy, bool protect, + bool& protOperationPerformed, bool selfChip, bool selfCopy, + bool allChips, bool allCopies, uint8_t arrIdx); + void determineAndExecuteReboot(RebootFile& rf, bool& needsReboot, xsc::Chip& tgtChip, + xsc::Copy& tgtCopy); + void resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy); + void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy); + bool parseRebootFile(std::string path, RebootFile& file); + void rewriteRebootFile(RebootFile file); + void readHkData(); }; #endif /* BSP_Q7S_CORE_CORECONTROLLER_H_ */ diff --git a/bsp_q7s/core/CoreDefinitions.h b/bsp_q7s/core/CoreDefinitions.h new file mode 100644 index 00000000..91896301 --- /dev/null +++ b/bsp_q7s/core/CoreDefinitions.h @@ -0,0 +1,39 @@ +#ifndef BSP_Q7S_CORE_COREDEFINITIONS_H_ +#define BSP_Q7S_CORE_COREDEFINITIONS_H_ + +#include + +namespace core { + +static const uint8_t HK_SET_ENTRIES = 3; +static const uint32_t HK_SET_ID = 5; + +enum PoolIds { TEMPERATURE, PS_VOLTAGE, PL_VOLTAGE }; + +/** + * @brief Set storing OBC internal housekeeping data + */ +class HkSet : public StaticLocalDataSet { + public: + HkSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, HK_SET_ID) {} + + HkSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, HK_SET_ID)) {} + + // On-chip temperature + lp_var_t temperature = lp_var_t(sid.objectId, PoolIds::TEMPERATURE, this); + // Processing system VCC + lp_var_t psVoltage = lp_var_t(sid.objectId, PoolIds::PS_VOLTAGE, this); + // Programmable logic VCC + lp_var_t plVoltage = lp_var_t(sid.objectId, PoolIds::PL_VOLTAGE, this); + + void printSet() { + sif::info << "HkSet::printSet: On-chip temperature: " << this->temperature << " °C" + << std::endl; + sif::info << "HkSet::printSet: PS voltage: " << this->psVoltage << " mV" << std::endl; + sif::info << "HkSet::printSet: PL voltage: " << this->plVoltage << " mV" << std::endl; + } +}; + +} // namespace core + +#endif /* BSP_Q7S_CORE_COREDEFINITIONS_H_ */ diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 7977deed..1d502fef 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -1,22 +1,21 @@ #include "InitMission.h" -#include "ObjectFactory.h" -#include "OBSWConfig.h" -#include "pollingsequence/pollingSequenceFactory.h" - -#include "mission/utility/InitMission.h" - -#include "fsfw/platform.h" -#include "fsfw/objectmanager/ObjectManagerIF.h" -#include "fsfw/returnvalues/HasReturnvaluesIF.h" -#include "fsfw/serviceinterface/ServiceInterfaceStream.h" -#include "fsfw/objectmanager/ObjectManager.h" -#include "fsfw/tasks/FixedTimeslotTaskIF.h" -#include "fsfw/tasks/PeriodicTaskIF.h" -#include "fsfw/tasks/TaskFactory.h" #include #include +#include "OBSWConfig.h" +#include "ObjectFactory.h" +#include "fsfw/objectmanager/ObjectManager.h" +#include "fsfw/objectmanager/ObjectManagerIF.h" +#include "fsfw/platform.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw/serviceinterface/ServiceInterfaceStream.h" +#include "fsfw/tasks/FixedTimeslotTaskIF.h" +#include "fsfw/tasks/PeriodicTaskIF.h" +#include "fsfw/tasks/TaskFactory.h" +#include "mission/utility/InitMission.h" +#include "pollingsequence/pollingSequenceFactory.h" + /* This is configured for linux without CR */ #ifdef PLATFORM_UNIX ServiceInterfaceStream sif::debug("DEBUG"); @@ -30,335 +29,407 @@ ServiceInterfaceStream sif::warning("WARNING", true); ServiceInterfaceStream sif::error("ERROR", true, false, true); #endif -ObjectManagerIF *objectManager = nullptr; +ObjectManagerIF* objectManager = nullptr; void initmission::initMission() { + sif::info << "Building global objects.." << std::endl; + /* Instantiate global object manager and also create all objects */ + ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr); + sif::info << "Initializing all objects.." << std::endl; + ObjectManager::instance()->initialize(); - sif::info << "Building global objects.." << std::endl; - /* Instantiate global object manager and also create all objects */ - ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr); - sif::info << "Initializing all objects.." << std::endl; - ObjectManager::instance()->initialize(); - - /* This function creates and starts all tasks */ - initTasks(); + /* This function creates and starts all tasks */ + initTasks(); } void initmission::initTasks() { - TaskFactory* factory = TaskFactory::instance(); - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - if(factory == nullptr) { - /* Should never happen ! */ - return; - } + TaskFactory* factory = TaskFactory::instance(); + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if (factory == nullptr) { + /* Should never happen ! */ + return; + } #if OBSW_PRINT_MISSED_DEADLINES == 1 - void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline; + void (*missedDeadlineFunc)(void) = TaskFactory::printMissedDeadline; #else - void (*missedDeadlineFunc) (void) = nullptr; + void (*missedDeadlineFunc)(void) = nullptr; #endif -#if BOARD_TE0720 == 0 - PeriodicTaskIF* coreController = factory->createPeriodicTask( - "CORE_CTRL", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc); - result = coreController->addComponent(objects::CORE_CONTROLLER); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("CORE_CTRL", objects::CORE_CONTROLLER); - } -#endif + PeriodicTaskIF* coreController = factory->createPeriodicTask( + "CORE_CTRL", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc); + result = coreController->addComponent(objects::CORE_CONTROLLER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("CORE_CTRL", objects::CORE_CONTROLLER); + } - /* TMTC Distribution */ - PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( - "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR); - } - result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR); - } - result = tmTcDistributor->addComponent(objects::TM_FUNNEL); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL); - } + /* TMTC Distribution */ + PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR); + } + result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR); + } + result = tmTcDistributor->addComponent(objects::TM_FUNNEL); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL); + } #if OBSW_ADD_TCPIP_BRIDGE == 1 - // TMTC bridge - PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask( - "TCPIP_TMTC_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("UDP_BRIDGE", objects::TMTC_BRIDGE); - } - PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( - "TMTC_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("UDP_POLLING", objects::TMTC_POLLING_TASK); - } + // TMTC bridge + PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask( + "TCPIP_TMTC_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("TMTC_BRIDGE", objects::TMTC_BRIDGE); + } + PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( + "TMTC_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("UDP_POLLING", objects::TMTC_POLLING_TASK); + } #endif #if OBSW_USE_CCSDS_IP_CORE == 1 - PeriodicTaskIF* ccsdsHandlerTask = factory->createPeriodicTask( - "CCSDS_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = ccsdsHandlerTask->addComponent(objects::CCSDS_HANDLER); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("CCSDS Handler", objects::CCSDS_HANDLER); - } + PeriodicTaskIF* ccsdsHandlerTask = factory->createPeriodicTask( + "CCSDS_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + result = ccsdsHandlerTask->addComponent(objects::CCSDS_HANDLER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("CCSDS Handler", objects::CCSDS_HANDLER); + } - // Minimal distance between two received TCs amounts to 0.6 seconds - // If a command has not been read before the next one arrives, the old command will be - // overwritten by the PDEC. - PeriodicTaskIF* pdecHandlerTask = factory->createPeriodicTask( - "PDEC_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc); - result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER); - } + // Minimal distance between two received TCs amounts to 0.6 seconds + // If a command has not been read before the next one arrives, the old command will be + // overwritten by the PDEC. + PeriodicTaskIF* pdecHandlerTask = factory->createPeriodicTask( + "PDEC_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc); + result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER); + } #endif /* OBSW_USE_CCSDS_IP_CORE == 1 */ -# if BOARD_TE0720 == 0 - // FS task, task interval does not matter because it runs in permanent loop, priority low - // because it is a non-essential background task - PeriodicTaskIF* fsTask = factory->createPeriodicTask( - "FILE_SYSTEM_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc); - result = fsTask->addComponent(objects::FILE_SYSTEM_HANDLER); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::FILE_SYSTEM_HANDLER); - } +#if OBSW_ADD_ACS_HANDLERS == 1 + PeriodicTaskIF* acsTask = factory->createPeriodicTask( + "ACS_CTRL", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); + result = acsTask->addComponent(objects::GPS_CONTROLLER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("GPS_CTRL", objects::GPS_CONTROLLER); + } + +#endif /* OBSW_ADD_ACS_HANDLERS */ + + PeriodicTaskIF* sysTask = factory->createPeriodicTask( + "SYS_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); + result = sysTask->addComponent(objects::ACS_BOARD_ASS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("ACS_ASS", objects::ACS_BOARD_ASS); + } + result = sysTask->addComponent(objects::SUS_BOARD_ASS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("SUS_ASS", objects::SUS_BOARD_ASS); + } + result = sysTask->addComponent(objects::TCS_BOARD_ASS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("TCS_BOARD_ASS", objects::TCS_BOARD_ASS); + } + + // FS task, task interval does not matter because it runs in permanent loop, priority low + // because it is a non-essential background task + PeriodicTaskIF* fsTask = factory->createPeriodicTask( + "FILE_SYSTEM_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc); + result = fsTask->addComponent(objects::FILE_SYSTEM_HANDLER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::FILE_SYSTEM_HANDLER); + } #if OBSW_ADD_STAR_TRACKER == 1 - PeriodicTaskIF* strImgLoaderTask = factory->createPeriodicTask( - "FILE_SYSTEM_TASK", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = strImgLoaderTask->addComponent(objects::STR_HELPER); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::STR_HELPER); - } + PeriodicTaskIF* strHelperTask = factory->createPeriodicTask( + "STR_HELPER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = strHelperTask->addComponent(objects::STR_HELPER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("STR_HELPER", objects::STR_HELPER); + } #endif /* OBSW_ADD_STAR_TRACKER == 1 */ -#endif /* BOARD_TE0720 */ +#if OBSW_ADD_PLOC_MPSOC == 1 + PeriodicTaskIF* mpsocHelperTask = factory->createPeriodicTask( + "PLOC_MPSOC_HELPER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = mpsocHelperTask->addComponent(objects::PLOC_MPSOC_HELPER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PLOC_MPSOC_HELPER", objects::PLOC_MPSOC_HELPER); + } +#endif /* OBSW_ADD_PLOC_MPSOC */ #if OBSW_TEST_CCSDS_BRIDGE == 1 - PeriodicTaskIF* ptmeTestTask = factory->createPeriodicTask( - "PTME_TEST", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = ptmeTestTask->addComponent(objects::CCSDS_IP_CORE_BRIDGE); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PTME_TEST", objects::CCSDS_IP_CORE_BRIDGE); - } + PeriodicTaskIF* ptmeTestTask = factory->createPeriodicTask( + "PTME_TEST", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + result = ptmeTestTask->addComponent(objects::CCSDS_IP_CORE_BRIDGE); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PTME_TEST", objects::CCSDS_IP_CORE_BRIDGE); + } #endif - std::vector pusTasks; - createPusTasks(*factory, missedDeadlineFunc, pusTasks); - std::vector pstTasks; - createPstTasks(*factory, missedDeadlineFunc, pstTasks); + std::vector pusTasks; + createPusTasks(*factory, missedDeadlineFunc, pusTasks); + std::vector pstTasks; + createPstTasks(*factory, missedDeadlineFunc, pstTasks); #if OBSW_ADD_TEST_CODE == 1 - std::vector testTasks; - createTestTasks(*factory, missedDeadlineFunc, testTasks); + std::vector testTasks; + createTestTasks(*factory, missedDeadlineFunc, testTasks); #endif - auto taskStarter = [](std::vector& taskVector, std::string name) { - for(const auto& task: taskVector) { - if(task != nullptr) { - task->startTask(); - } - else { - sif::error << "Task in vector " << name << " is invalid!" << std::endl; - } - } - }; + auto taskStarter = [](std::vector& taskVector, std::string name) { + for (const auto& task : taskVector) { + if (task != nullptr) { + task->startTask(); + } else { + sif::error << "Task in vector " << name << " is invalid!" << std::endl; + } + } + }; - sif::info << "Starting tasks.." << std::endl; - tmTcDistributor->startTask(); + sif::info << "Starting tasks.." << std::endl; + tmTcDistributor->startTask(); #if OBSW_ADD_TCPIP_BRIDGE == 1 - tmtcBridgeTask->startTask(); - tmtcPollingTask->startTask(); + tmtcBridgeTask->startTask(); + tmtcPollingTask->startTask(); #endif #if OBSW_USE_CCSDS_IP_CORE == 1 - ccsdsHandlerTask->startTask(); - pdecHandlerTask->startTask(); + ccsdsHandlerTask->startTask(); + pdecHandlerTask->startTask(); #endif /* OBSW_USE_CCSDS_IP_CORE == 1 */ -#if BOARD_TE0720 == 0 - coreController->startTask(); -#endif + coreController->startTask(); - taskStarter(pstTasks, "PST task vector"); - taskStarter(pusTasks, "PUS task vector"); + taskStarter(pstTasks, "PST task vector"); + taskStarter(pusTasks, "PUS task vector"); #if OBSW_ADD_TEST_CODE == 1 - taskStarter(testTasks, "Test task vector"); + taskStarter(testTasks, "Test task vector"); #endif #if OBSW_TEST_CCSDS_BRIDGE == 1 - ptmeTestTask->startTask(); + ptmeTestTask->startTask(); #endif -#if BOARD_TE0720 == 0 - fsTask->startTask(); + fsTask->startTask(); #if OBSW_ADD_STAR_TRACKER == 1 - strImgLoaderTask->startTask(); + strHelperTask->startTask(); #endif /* OBSW_ADD_STAR_TRACKER == 1 */ -#endif - sif::info << "Tasks started.." << std::endl; +#if OBSW_ADD_ACS_HANDLERS == 1 + acsTask->startTask(); +#endif + sysTask->startTask(); + + sif::info << "Tasks started.." << std::endl; } void initmission::createPstTasks(TaskFactory& factory, - TaskDeadlineMissedFunction missedDeadlineFunc, std::vector &taskVec) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; -#if BOARD_TE0720 == 0 - /* Polling Sequence Table Default */ + TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + /* Polling Sequence Table Default */ #if OBSW_ADD_SPI_TEST_CODE == 0 - FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask( - "PST_TASK_DEFAULT", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, - missedDeadlineFunc); - result = pst::pstSpi(spiPst); - if (result != HasReturnvaluesIF::RETURN_OK) { - if(result != FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { - sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; - } - } - else { - taskVec.push_back(spiPst); + FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask( + "PST_TASK_DEFAULT", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc); + result = pst::pstSpi(spiPst); + if (result != HasReturnvaluesIF::RETURN_OK) { + if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { + sif::warning << "InitMission::initTasks: SPI PST is empty" << std::endl; + } else { + sif::error << "InitMission::initTasks: Creating SPI PST failed!" << std::endl; } + } else { + taskVec.push_back(spiPst); + } #endif - FixedTimeslotTaskIF* uartPst = factory.createFixedTimeslotTask( - "UART_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); - result = pst::pstUart(uartPst); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; + FixedTimeslotTaskIF* uartPst = factory.createFixedTimeslotTask( + "UART_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); + result = pst::pstUart(uartPst); + if (result != HasReturnvaluesIF::RETURN_OK) { + if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { + sif::warning << "InitMission::initTasks: UART PST is empty" << std::endl; + } else { + sif::error << "InitMission::initTasks: Creating UART PST failed!" << std::endl; } + } else { taskVec.push_back(uartPst); - FixedTimeslotTaskIF* gpioPst = factory.createFixedTimeslotTask( - "GPIO_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); - result = pst::pstGpio(gpioPst); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; + } + + FixedTimeslotTaskIF* gpioPst = factory.createFixedTimeslotTask( + "GPIO_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); + result = pst::pstGpio(gpioPst); + if (result != HasReturnvaluesIF::RETURN_OK) { + if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { + sif::warning << "InitMission::initTasks: GPIO PST is empty" << std::endl; + } else { + sif::error << "InitMission::initTasks: Creating GPIO PST failed!" << std::endl; } + } else { taskVec.push_back(gpioPst); - FixedTimeslotTaskIF* i2cPst = factory.createFixedTimeslotTask( - "I2C_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); - result = pst::pstI2c(i2cPst); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; + } +#if OBSW_ADD_I2C_TEST_CODE == 0 + FixedTimeslotTaskIF* i2cPst = factory.createFixedTimeslotTask( + "I2C_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); + result = pst::pstI2c(i2cPst); + if (result != HasReturnvaluesIF::RETURN_OK) { + if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { + sif::warning << "InitMission::initTasks: I2C PST is empty" << std::endl; + } else { + sif::error << "InitMission::initTasks: Creating I2C PST failed!" << std::endl; } - - FixedTimeslotTaskIF* gomSpacePstTask = factory.createFixedTimeslotTask( - "GS_PST_TASK", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 1.0, missedDeadlineFunc); - result = pst::pstGompaceCan(gomSpacePstTask); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl; - } - taskVec.push_back(gomSpacePstTask); -#else /* BOARD_TE7020 == 0 */ - FixedTimeslotTaskIF * pollingSequenceTaskTE0720 = factory.createFixedTimeslotTask( - "PST_TASK_TE0720", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE * 8, 3.0, - missedDeadlineFunc); - result = pst::pollingSequenceTE0720(pollingSequenceTaskTE0720); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: Creating TE0720 PST failed!" << std::endl; - } - taskVec.push_back(pollingSequenceTaskTE0720); -#endif /* BOARD_TE7020 == 1 */ -} - -void initmission::createPusTasks(TaskFactory &factory, - TaskDeadlineMissedFunction missedDeadlineFunc, std::vector &taskVec) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - /* PUS Services */ - PeriodicTaskIF* pusVerification = factory.createPeriodicTask( - "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION); - } - taskVec.push_back(pusVerification); - - PeriodicTaskIF* pusEvents = factory.createPeriodicTask( - "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); - } - result = pusEvents->addComponent(objects::EVENT_MANAGER); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER); - } - taskVec.push_back(pusEvents); - - PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask( - "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS); - } - result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT); - } - taskVec.push_back(pusHighPrio); - - PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask( - "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); - result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT); - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT); - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); - } - taskVec.push_back(pusMedPrio); - - PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask( - "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); - result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST); - } - result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("ERROR_REPORTER", objects::INTERNAL_ERROR_REPORTER); - } - taskVec.push_back(pusLowPrio); -} - -void initmission::createTestTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, - std::vector& taskVec) { -#if OBSW_ADD_TEST_TASK == 1 || OBSW_ADD_SPI_TEST_CODE == 1 || (BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1) - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + } else { + taskVec.push_back(i2cPst); + } #endif - PeriodicTaskIF* testTask = factory.createPeriodicTask( - "TEST_TASK", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc); -#if OBSW_ADD_TEST_TASK == 1 - result = testTask->addComponent(objects::TEST_TASK); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + + FixedTimeslotTaskIF* gomSpacePstTask = factory.createFixedTimeslotTask( + "GS_PST_TASK", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 1.0, missedDeadlineFunc); + result = pst::pstGompaceCan(gomSpacePstTask); + if (result != HasReturnvaluesIF::RETURN_OK) { + if (result != FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { + sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl; } -#endif /* OBSW_ADD_TEST_TASK == 1 */ + } + taskVec.push_back(gomSpacePstTask); +} + +void initmission::createPusTasks(TaskFactory& factory, + TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + /* PUS Services */ + PeriodicTaskIF* pusVerification = factory.createPeriodicTask( + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION); + } + taskVec.push_back(pusVerification); + + PeriodicTaskIF* pusEvents = factory.createPeriodicTask( + "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); + } + result = pusEvents->addComponent(objects::EVENT_MANAGER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER); + } + taskVec.push_back(pusEvents); + + PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask( + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS); + } + result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT); + } + taskVec.push_back(pusHighPrio); + + PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask( + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); + } + taskVec.push_back(pusMedPrio); + + PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST); + } + result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("ERROR_REPORTER", objects::INTERNAL_ERROR_REPORTER); + } + taskVec.push_back(pusLowPrio); +} + +void initmission::createTestTasks(TaskFactory& factory, + TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec) { +#if OBSW_ADD_TEST_TASK == 1 && OBSW_ADD_TEST_CODE == 1 + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + static_cast(result); // supress warning in case it is not used + + PeriodicTaskIF* testTask = factory.createPeriodicTask( + "TEST_TASK", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc); + + result = testTask->addComponent(objects::TEST_TASK); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + } #if OBSW_ADD_SPI_TEST_CODE == 1 - result = testTask->addComponent(objects::SPI_TEST); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST); - } + result = testTask->addComponent(objects::SPI_TEST); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST); + } #endif -#if BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1 - result = testTask->addComponent(objects::LIBGPIOD_TEST); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); - } -#endif /* BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1 */ - taskVec.push_back(testTask); +#if OBSW_ADD_I2C_TEST_CODE == 1 + result = testTask->addComponent(objects::I2C_TEST); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("I2C_TEST", objects::I2C_TEST); + } +#endif +#if OBSW_ADD_UART_TEST_CODE == 1 + result = testTask->addComponent(objects::UART_TEST); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("UART_TEST", objects::UART_TEST); + } +#endif + + taskVec.push_back(testTask); + +#endif // OBSW_ADD_TEST_TASK == 1 && OBSW_ADD_TEST_CODE == 1 } + +/** + â–„ â–„ + ▌▒█ ▄▀▒▌ + ▌▒▒█ ▄▀▒▒▒■+ â–▄▀▒▒▀▀▀▀▄▄▄▀▒▒▒▒▒■+ ▄▄▀▒░▒▒▒▒▒▒▒▒▒█▒▒▄█▒■+ ▄▀▒▒▒░░░▒▒▒░░░▒▒▒▀██▀▒▌ + â–▒▒▒▄▄▒▒▒▒░░░▒▒▒▒▒▒▒▀▄▒▒▌ + ▌░░▌█▀▒▒▒▒▒▄▀█▄▒▒▒▒▒▒▒█▒■+ â–░░░▒▒▒▒▒▒▒▒▌██▀▒▒░░░▒▒▒▀▄▌ + ▌░▒▄██▄▒▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒▌ + ▌▒▀â–▄█▄█▌▄░▀▒▒░░░░░░░░░░▒▒▒■+ â–â–’â–’â–â–€â–▀▒░▄▄▒▄▒▒▒▒▒▒░▒░▒░▒▒▒▒▌ + â–▒▒▒▀▀▄▄▒▒▒▄▒▒▒▒▒▒▒▒░▒░▒░▒▒■+ ▌▒▒▒▒▒▒▀▀▀▒▒▒▒▒▒░▒░▒░▒░▒▒▒▌ + â–â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–‘â–’â–‘â–’â–‘â–’â–’â–„â–’â–’â– + ▀▄▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▄▒▒▒▒▌ + ▀▄▒▒▒▒▒▒▒▒▒▒▄▄▄▀▒▒▒▒▄▀ + ▀▄▄▄▄▄▄▀▀▀▒▒▒▒▒▄▄▀ + ▒▒▒▒▒▒▒▒▒▒▀▀ + **/ diff --git a/bsp_q7s/core/InitMission.h b/bsp_q7s/core/InitMission.h index ffdfc11c..5c509b79 100644 --- a/bsp_q7s/core/InitMission.h +++ b/bsp_q7s/core/InitMission.h @@ -1,9 +1,10 @@ #ifndef BSP_Q7S_INITMISSION_H_ #define BSP_Q7S_INITMISSION_H_ -#include "fsfw/tasks/Typedef.h" #include +#include "fsfw/tasks/Typedef.h" + class PeriodicTaskIF; class TaskFactory; @@ -12,11 +13,11 @@ void initMission(); void initTasks(); void createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, - std::vector& taskVec); + std::vector& taskVec); void createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, - std::vector& taskVec); + std::vector& taskVec); void createTestTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, - std::vector& taskVec); -}; + std::vector& taskVec); +}; // namespace initmission #endif /* BSP_Q7S_INITMISSION_H_ */ diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 760e2a4a..064cdd71 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -1,1114 +1,1226 @@ -#include #include "ObjectFactory.h" -#include "bsp_q7s/devices/startracker/StrHelper.h" -#include "bsp_q7s/devices/startracker/StarTrackerDefinitions.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "OBSWConfig.h" -#include "devConf.h" -#include "ccsdsConfig.h" +#include "bsp_q7s/boardtest/Q7STestTask.h" +#include "bsp_q7s/callbacks/gnssCallback.h" +#include "bsp_q7s/callbacks/gpioCallbacks.h" +#include "bsp_q7s/callbacks/pcduSwitchCb.h" +#include "bsp_q7s/callbacks/rwSpiCallback.h" +#include "bsp_q7s/core/CoreController.h" +#include "bsp_q7s/memory/FileSystemHandler.h" #include "busConf.h" -#include "tmtc/apid.h" +#include "ccsdsConfig.h" +#include "devConf.h" #include "devices/addresses.h" #include "devices/gpioIds.h" -#include "tmtc/pusIds.h" #include "devices/powerSwitcherList.h" -#include "bsp_q7s/gpio/gpioCallbacks.h" -#include "bsp_q7s/core/CoreController.h" -#include "bsp_q7s/boardtest/Q7STestTask.h" -#include "bsp_q7s/memory/FileSystemHandler.h" -#include "bsp_q7s/devices/PlocSupervisorHandler.h" -#include "bsp_q7s/devices/PlocUpdater.h" -#include "bsp_q7s/devices/PlocMemoryDumper.h" -#include "bsp_q7s/devices/startracker/StarTrackerHandler.h" -#include "bsp_q7s/callbacks/rwSpiCallback.h" -#include "bsp_q7s/callbacks/gnssCallback.h" - -#include "linux/devices/SolarArrayDeploymentHandler.h" -#include "linux/devices/devicedefinitions/SusDefinitions.h" -#include "linux/devices/SusHandler.h" -#include "linux/csp/CspCookie.h" -#include "linux/csp/CspComIF.h" - -#include "mission/devices/HeaterHandler.h" -#include "mission/core/GenericFactory.h" -#include "mission/devices/PDU1Handler.h" -#include "mission/devices/PDU2Handler.h" -#include "mission/devices/ACUHandler.h" -#include "mission/devices/PCDUHandler.h" -#include "mission/devices/P60DockHandler.h" -#include "mission/devices/Tmp1075Handler.h" -#include "mission/devices/Max31865PT1000Handler.h" -#include "mission/devices/GyroADIS1650XHandler.h" -#include "mission/devices/IMTQHandler.h" -#include "mission/devices/SyrlinksHkHandler.h" -#include "mission/devices/PlocMPSoCHandler.h" -#include "mission/devices/RadiationSensorHandler.h" -#include "mission/devices/RwHandler.h" -#include "mission/devices/devicedefinitions/GomspaceDefinitions.h" -#include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" -#include "mission/devices/devicedefinitions/PlocMPSoCDefinitions.h" -#include "mission/devices/devicedefinitions/RadSensorDefinitions.h" -#include "mission/devices/devicedefinitions/Max31865Definitions.h" -#include "mission/devices/devicedefinitions/RwDefinitions.h" - -#include "mission/devices/GPSHyperionHandler.h" -#include "mission/tmtc/CCSDSHandler.h" -#include "mission/tmtc/VirtualChannel.h" -#include "mission/utility/TmFunnel.h" - -#include "fsfw_hal/linux/uart/UartComIF.h" -#include "fsfw_hal/linux/uart/UartCookie.h" -#include "fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h" -#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h" -#include "fsfw_hal/devicehandlers/MgmRM3100Handler.h" -#include "fsfw_hal/linux/i2c/I2cCookie.h" -#include "fsfw_hal/linux/i2c/I2cComIF.h" -#include "fsfw_hal/linux/spi/SpiCookie.h" -#include "fsfw_hal/linux/spi/SpiComIF.h" -#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" -#include "fsfw_hal/common/gpio/GpioCookie.h" - -#include "fsfw/datapoollocal/LocalDataPoolManager.h" -#include "fsfw/tmtcservices/CommandingServiceBase.h" -#include "fsfw/tmtcservices/PusServiceBase.h" -#include "fsfw/tmtcpacket/pus/tm.h" - +#include "linux/boardtest/I2cTestClass.h" #include "linux/boardtest/SpiTestClass.h" +#include "linux/boardtest/UartTestClass.h" +#include "linux/csp/CspComIF.h" +#include "linux/csp/CspCookie.h" +#include "linux/devices/GPSHyperionLinuxController.h" +#include "linux/devices/devicedefinitions/PlocMPSoCDefinitions.h" +#include "linux/devices/devicedefinitions/StarTrackerDefinitions.h" +#include "linux/devices/ploc/PlocMPSoCHandler.h" +#include "linux/devices/ploc/PlocMPSoCHelper.h" +#include "linux/devices/ploc/PlocMemoryDumper.h" +#include "linux/devices/ploc/PlocSupervisorHandler.h" +#include "linux/devices/ploc/PlocUpdater.h" +#include "linux/devices/startracker/StarTrackerHandler.h" +#include "linux/devices/startracker/StrHelper.h" +#include "tmtc/apid.h" +#include "tmtc/pusIds.h" #if OBSW_TEST_LIBGPIOD == 1 #include "linux/boardtest/LibgpiodTest.h" #endif -#include -#include -#include -#include -#include -#include +#include + +#include "fsfw/datapoollocal/LocalDataPoolManager.h" +#include "fsfw/tmtcpacket/pus/tm.h" +#include "fsfw/tmtcservices/CommandingServiceBase.h" +#include "fsfw/tmtcservices/PusServiceBase.h" +#include "fsfw_hal/common/gpio/GpioCookie.h" +#include "fsfw_hal/common/gpio/gpioDefinitions.h" +#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h" +#include "fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h" +#include "fsfw_hal/devicehandlers/MgmRM3100Handler.h" +#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" +#include "fsfw_hal/linux/i2c/I2cComIF.h" +#include "fsfw_hal/linux/i2c/I2cCookie.h" +#include "fsfw_hal/linux/spi/SpiComIF.h" +#include "fsfw_hal/linux/spi/SpiCookie.h" +#include "fsfw_hal/linux/uart/UartComIF.h" +#include "fsfw_hal/linux/uart/UartCookie.h" +#include "mission/core/GenericFactory.h" +#include "mission/devices/ACUHandler.h" +#include "mission/devices/BpxBatteryHandler.h" +#include "mission/devices/GyroADIS1650XHandler.h" +#include "mission/devices/HeaterHandler.h" +#include "mission/devices/IMTQHandler.h" +#include "mission/devices/Max31865PT1000Handler.h" +#include "mission/devices/P60DockHandler.h" +#include "mission/devices/PCDUHandler.h" +#include "mission/devices/PDU1Handler.h" +#include "mission/devices/PDU2Handler.h" +#include "mission/devices/PayloadPcduHandler.h" +#include "mission/devices/RadiationSensorHandler.h" +#include "mission/devices/RwHandler.h" +#include "mission/devices/SolarArrayDeploymentHandler.h" +#include "mission/devices/SusHandler.h" +#include "mission/devices/SyrlinksHkHandler.h" +#include "mission/devices/Tmp1075Handler.h" +#include "mission/devices/devicedefinitions/GomspaceDefinitions.h" +#include "mission/devices/devicedefinitions/Max31865Definitions.h" +#include "mission/devices/devicedefinitions/RadSensorDefinitions.h" +#include "mission/devices/devicedefinitions/RwDefinitions.h" +#include "mission/devices/devicedefinitions/SusDefinitions.h" +#include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" +#include "mission/devices/devicedefinitions/payloadPcduDefinitions.h" +#include "mission/system/AcsBoardAssembly.h" +#include "mission/tmtc/CCSDSHandler.h" +#include "mission/tmtc/VirtualChannel.h" +#include "mission/utility/TmFunnel.h" ResetArgs resetArgsGnss0; ResetArgs resetArgsGnss1; -void ObjectFactory::setStatics() { - Factory::setStaticFrameworkObjectIds(); -} +void ObjectFactory::setStatics() { Factory::setStaticFrameworkObjectIds(); } void Factory::setStaticFrameworkObjectIds() { - PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; - PusServiceBase::packetDestination = objects::TM_FUNNEL; + PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; + PusServiceBase::packetDestination = objects::TM_FUNNEL; - CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; - CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; + CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; + CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; - //DeviceHandlerBase::powerSwitcherId = objects::PCDU_HANDLER; - DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; + DeviceHandlerBase::powerSwitcherId = objects::PCDU_HANDLER; + // DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; #if OBSW_TM_TO_PTME == 1 - TmFunnel::downlinkDestination = objects::CCSDS_HANDLER; + TmFunnel::downlinkDestination = objects::CCSDS_HANDLER; #else - TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; + TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; #endif /* OBSW_TM_TO_PTME == 1 */ - // No storage object for now. - TmFunnel::storageDestination = objects::NO_OBJECT; + // No storage object for now. + TmFunnel::storageDestination = objects::NO_OBJECT; - LocalDataPoolManager::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING; + LocalDataPoolManager::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING; - VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION; - TmPacketBase::timeStamperId = objects::TIME_STAMPER; + VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION; + TmPacketBase::timeStamperId = objects::TIME_STAMPER; } void ObjectFactory::produce(void* args) { - ObjectFactory::setStatics(); - ObjectFactory::produceGenericObjects(); + ObjectFactory::setStatics(); + ObjectFactory::produceGenericObjects(); - LinuxLibgpioIF* gpioComIF = nullptr; - UartComIF* uartComIF = nullptr; - SpiComIF* spiComIF = nullptr; - createCommunicationInterfaces(&gpioComIF, &uartComIF, &spiComIF); - createTmpComponents(); -#if BOARD_TE0720 == 0 - new CoreController(objects::CORE_CONTROLLER); + LinuxLibgpioIF* gpioComIF = nullptr; + UartComIF* uartComIF = nullptr; + SpiComIF* spiComIF = nullptr; + I2cComIF* i2cComIF = nullptr; + PowerSwitchIF* pwrSwitcher = nullptr; + createCommunicationInterfaces(&gpioComIF, &uartComIF, &spiComIF, &i2cComIF); + createTmpComponents(); + new CoreController(objects::CORE_CONTROLLER); - createPcduComponents(); - createRadSensorComponent(gpioComIF); - createSunSensorComponents(gpioComIF, spiComIF); + gpioCallbacks::disableAllDecoder(); + createPcduComponents(gpioComIF, &pwrSwitcher); + createRadSensorComponent(gpioComIF); + createSunSensorComponents(gpioComIF, spiComIF, pwrSwitcher); #if OBSW_ADD_ACS_BOARD == 1 - createAcsBoardComponents(gpioComIF, uartComIF); -#endif /* OBSW_ADD_ACS_BOARD == 1 */ - createHeaterComponents(); - createSolarArrayDeploymentComponents(); + createAcsBoardComponents(gpioComIF, uartComIF, pwrSwitcher); +#endif + + createHeaterComponents(); + createSolarArrayDeploymentComponents(); + createPlPcduComponents(gpioComIF, spiComIF); #if OBSW_ADD_SYRLINKS == 1 - createSyrlinksComponents(); + createSyrlinksComponents(); #endif /* OBSW_ADD_SYRLINKS == 1 */ + createRtdComponents(gpioComIF, pwrSwitcher); + createPayloadComponents(gpioComIF); -#if OBSW_ADD_RTD_DEVICES == 1 - createRtdComponents(gpioComIF); -#endif /* OBSW_ADD_RTD_DEVICES == 1 */ +#if OBSW_ADD_MGT == 1 + I2cCookie* imtqI2cCookie = + new I2cCookie(addresses::IMTQ, IMTQ::MAX_REPLY_SIZE, q7s::I2C_DEFAULT_DEV); + auto imtqHandler = new IMTQHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie); + static_cast(imtqHandler); +#if OBSW_DEBUG_IMTQ == 1 + imtqHandler->setStartUpImmediately(); + imtqHandler->setToGoToNormal(true); +#else + (void)imtqHandler; +#endif +#endif + createReactionWheelComponents(gpioComIF); - I2cCookie* imtqI2cCookie = new I2cCookie(addresses::IMTQ, IMTQ::MAX_REPLY_SIZE, - q7s::I2C_DEFAULT_DEV); - new IMTQHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie); - createReactionWheelComponents(gpioComIF); +#if OBSW_ADD_BPX_BATTERY_HANDLER == 1 + I2cCookie* bpxI2cCookie = new I2cCookie(addresses::BPX_BATTERY, 100, q7s::I2C_DEFAULT_DEV); + BpxBatteryHandler* bpxHandler = + new BpxBatteryHandler(objects::BPX_BATT_HANDLER, objects::I2C_COM_IF, bpxI2cCookie); +#if OBSW_TEST_BPX_BATT == 1 + bpxHandler->setToGoToNormalMode(true); + bpxHandler->setStartUpImmediately(); +#else + static_cast(bpxHandler); +#endif +#endif -#if OBSW_ADD_PLOC_MPSOC == 1 - UartCookie* plocMpsocCookie = new UartCookie(objects::PLOC_MPSOC_HANDLER, - q7s::UART_PLOC_MPSOC_DEV, UartModes::NON_CANONICAL, uart::PLOC_MPSOC_BAUD, -<<<<<<< Updated upstream - PLOC_MPSOC::MAX_REPLY_SIZE); - new PlocMPSoCHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, plocMpsocCookie); -======= - mpsoc::MAX_REPLY_SIZE); - PlocMPSoCHandler* plocMpsocHandler = new PlocMPSoCHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, plocMpsocCookie); - plocMpsocHandler->setStartUpImmediately(); ->>>>>>> Stashed changes -#endif /* OBSW_ADD_PLOC_MPSOC == 1 */ - -#if OBSW_ADD_PLOC_SUPERVISOR == 1 - UartCookie* plocSupervisorCookie = new UartCookie(objects::PLOC_SUPERVISOR_HANDLER, - q7s::UART_PLOC_SUPERVSIOR_DEV, UartModes::NON_CANONICAL, uart::PLOC_SUPERVISOR_BAUD, - PLOC_SPV::MAX_PACKET_SIZE * 20); - plocSupervisorCookie->setNoFixedSizeReply(); - PlocSupervisorHandler* plocSupervisor = new PlocSupervisorHandler( - objects::PLOC_SUPERVISOR_HANDLER, objects::UART_COM_IF, plocSupervisorCookie); - plocSupervisor->setStartUpImmediately(); -#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */ - - new FileSystemHandler(objects::FILE_SYSTEM_HANDLER); + new FileSystemHandler(objects::FILE_SYSTEM_HANDLER); #if OBSW_ADD_STAR_TRACKER == 1 - UartCookie* starTrackerCookie = new UartCookie(objects::STAR_TRACKER, - q7s::UART_STAR_TRACKER_DEV, UartModes::NON_CANONICAL, uart::STAR_TRACKER_BAUD, - StarTracker::MAX_FRAME_SIZE* 2 + 2); - starTrackerCookie->setNoFixedSizeReply(); - StrHelper* strHelper = new StrHelper(objects::STR_HELPER); - StarTrackerHandler* starTrackerHandler = new StarTrackerHandler(objects::STAR_TRACKER, - objects::UART_COM_IF, starTrackerCookie, strHelper); - starTrackerHandler->setStartUpImmediately(); + UartCookie* starTrackerCookie = + new UartCookie(objects::STAR_TRACKER, q7s::UART_STAR_TRACKER_DEV, UartModes::NON_CANONICAL, + uart::STAR_TRACKER_BAUD, startracker::MAX_FRAME_SIZE * 2 + 2); + starTrackerCookie->setNoFixedSizeReply(); + StrHelper* strHelper = new StrHelper(objects::STR_HELPER); + new StarTrackerHandler(objects::STAR_TRACKER, objects::UART_COM_IF, starTrackerCookie, strHelper, + pcduSwitches::PDU1_CH2_STAR_TRACKER_5V); #endif /* OBSW_ADD_STAR_TRACKER == 1 */ -#endif /* TE7020 == 0 */ - #if OBSW_USE_CCSDS_IP_CORE == 1 - createCcsdsComponents(gpioComIF); + createCcsdsComponents(gpioComIF); #endif /* OBSW_USE_CCSDS_IP_CORE == 1 */ - /* Test Task */ + /* Test Task */ #if OBSW_ADD_TEST_CODE == 1 - createTestComponents(gpioComIF); + createTestComponents(gpioComIF); #endif /* OBSW_ADD_TEST_CODE == 1 */ - new PlocUpdater(objects::PLOC_UPDATER); - new PlocMemoryDumper(objects::PLOC_MEMORY_DUMPER); + new PlocUpdater(objects::PLOC_UPDATER); + new PlocMemoryDumper(objects::PLOC_MEMORY_DUMPER); } void ObjectFactory::createTmpComponents() { -#if BOARD_TE0720 == 1 - I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1, - TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0")); - I2cCookie* i2cCookieTmp1075tcs2 = new I2cCookie(addresses::TMP1075_TCS_2, - TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0")); -#else - I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1, - TMP1075::MAX_REPLY_LENGTH, q7s::I2C_DEFAULT_DEV); - I2cCookie* i2cCookieTmp1075tcs2 = new I2cCookie(addresses::TMP1075_TCS_2, - TMP1075::MAX_REPLY_LENGTH, q7s::I2C_DEFAULT_DEV); -#endif + I2cCookie* i2cCookieTmp1075tcs1 = + new I2cCookie(addresses::TMP1075_TCS_1, TMP1075::MAX_REPLY_LENGTH, q7s::I2C_DEFAULT_DEV); + I2cCookie* i2cCookieTmp1075tcs2 = + new I2cCookie(addresses::TMP1075_TCS_2, TMP1075::MAX_REPLY_LENGTH, q7s::I2C_DEFAULT_DEV); - /* Temperature sensors */ - Tmp1075Handler* tmp1075Handler_1 = new Tmp1075Handler(objects::TMP1075_HANDLER_1, - objects::I2C_COM_IF, i2cCookieTmp1075tcs1); - (void) tmp1075Handler_1; - Tmp1075Handler* tmp1075Handler_2 = new Tmp1075Handler(objects::TMP1075_HANDLER_2, - objects::I2C_COM_IF, i2cCookieTmp1075tcs2); - (void) tmp1075Handler_2; + /* Temperature sensors */ + Tmp1075Handler* tmp1075Handler_1 = + new Tmp1075Handler(objects::TMP1075_HANDLER_1, objects::I2C_COM_IF, i2cCookieTmp1075tcs1); + (void)tmp1075Handler_1; + Tmp1075Handler* tmp1075Handler_2 = + new Tmp1075Handler(objects::TMP1075_HANDLER_2, objects::I2C_COM_IF, i2cCookieTmp1075tcs2); + (void)tmp1075Handler_2; } -void ObjectFactory::createCommunicationInterfaces(LinuxLibgpioIF **gpioComIF, UartComIF** uartComIF, - SpiComIF** spiComIF) { - if (gpioComIF == nullptr or uartComIF == nullptr or spiComIF == nullptr) { - sif::error << "ObjectFactory::createCommunicationInterfaces: Invalid passed ComIF pointer" - << std::endl; - } - *gpioComIF = new LinuxLibgpioIF(objects::GPIO_IF); +void ObjectFactory::createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF, + SpiComIF** spiComIF, I2cComIF** i2cComIF) { + if (gpioComIF == nullptr or uartComIF == nullptr or spiComIF == nullptr) { + sif::error << "ObjectFactory::createCommunicationInterfaces: Invalid passed ComIF pointer" + << std::endl; + } + *gpioComIF = new LinuxLibgpioIF(objects::GPIO_IF); - /* Communication interfaces */ - new CspComIF(objects::CSP_COM_IF); - new I2cComIF(objects::I2C_COM_IF); - *uartComIF = new UartComIF(objects::UART_COM_IF); -#if OBSW_ADD_SPI_TEST_CODE == 0 - *spiComIF = new SpiComIF(objects::SPI_COM_IF, *gpioComIF); -#endif /* Q7S_ADD_SPI_TEST_CODE == 0 */ + /* Communication interfaces */ + new CspComIF(objects::CSP_COM_IF); + *i2cComIF = new I2cComIF(objects::I2C_COM_IF); + *uartComIF = new UartComIF(objects::UART_COM_IF); + *spiComIF = new SpiComIF(objects::SPI_COM_IF, *gpioComIF); -#if BOARD_TE0720 == 0 - /* Adding gpios for chip select decoding to the gpioComIf */ - gpioCallbacks::initSpiCsDecoder(*gpioComIF); -#endif + /* Adding gpios for chip select decoding to the gpioComIf */ + gpioCallbacks::initSpiCsDecoder(*gpioComIF); } -void ObjectFactory::createPcduComponents() { - CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, addresses::P60DOCK); - CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU1); - CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU2); - CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_LENGTH, addresses::ACU); - /* Device Handler */ - P60DockHandler* p60dockhandler = new P60DockHandler(objects::P60DOCK_HANDLER, - objects::CSP_COM_IF, p60DockCspCookie); - PDU1Handler* pdu1handler = new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, - pdu1CspCookie); - PDU2Handler* pdu2handler = new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, - pdu2CspCookie); - ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, - acuCspCookie); - new PCDUHandler(objects::PCDU_HANDLER, 50); +void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher) { + CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, addresses::P60DOCK); + CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU1); + CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU2); + CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_LENGTH, addresses::ACU); + /* Device Handler */ + P60DockHandler* p60dockhandler = + new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, p60DockCspCookie); + PDU1Handler* pdu1handler = + new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, pdu1CspCookie); + pdu1handler->assignChannelHookFunction(&pcdu::switchCallback, gpioComIF); + PDU2Handler* pdu2handler = + new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie); + pdu2handler->assignChannelHookFunction(&pcdu::switchCallback, gpioComIF); + ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie); + auto pcduHandler = new PCDUHandler(objects::PCDU_HANDLER, 50); - /** - * Setting PCDU devices to mode normal immediately after start up because PCDU is always - * running. - */ - p60dockhandler->setModeNormal(); - pdu1handler->setModeNormal(); - pdu2handler->setModeNormal(); - acuhandler->setModeNormal(); + /** + * Setting PCDU devices to mode normal immediately after start up because PCDU is always + * running. + */ + p60dockhandler->setModeNormal(); + pdu1handler->setModeNormal(); + pdu2handler->setModeNormal(); + acuhandler->setModeNormal(); + if (pwrSwitcher != nullptr) { + *pwrSwitcher = pcduHandler; + } } void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) { - GpioCookie* gpioCookieRadSensor = new GpioCookie; - std::stringstream consumer; - consumer << "0x" << std::hex << objects::RAD_SENSOR; - GpiodRegularByLineName* gpio = new GpiodRegularByLineName( - q7s::gpioNames::RAD_SENSOR_CHIP_SELECT, consumer.str(), gpio::DIR_OUT, gpio::HIGH); - gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, gpio); - gpioComIF->addGpios(gpioCookieRadSensor); + using namespace gpio; + GpioCookie* gpioCookieRadSensor = new GpioCookie; + std::stringstream consumer; + consumer << "0x" << std::hex << objects::RAD_SENSOR; + GpiodRegularByLineName* gpio = new GpiodRegularByLineName( + q7s::gpioNames::RAD_SENSOR_CHIP_SELECT, consumer.str(), Direction::OUT, Levels::HIGH); + gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, gpio); + gpio = new GpiodRegularByLineName(q7s::gpioNames::ENABLE_RADFET, consumer.str(), Direction::OUT, + Levels::LOW); + gpioCookieRadSensor->addGpio(gpioIds::ENABLE_RADFET, gpio); + gpioComIF->addGpios(gpioCookieRadSensor); - SpiCookie* spiCookieRadSensor = new SpiCookie(addresses::RAD_SENSOR, gpioIds::CS_RAD_SENSOR, - std::string(q7s::SPI_DEFAULT_DEV), RAD_SENSOR::READ_SIZE, spi::DEFAULT_MAX_1227_MODE, - spi::DEFAULT_MAX_1227_SPEED); - new RadiationSensorHandler(objects::RAD_SENSOR, objects::SPI_COM_IF, spiCookieRadSensor); + SpiCookie* spiCookieRadSensor = new SpiCookie( + addresses::RAD_SENSOR, gpioIds::CS_RAD_SENSOR, std::string(q7s::SPI_DEFAULT_DEV), + RAD_SENSOR::READ_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::DEFAULT_MAX_1227_SPEED); + auto radSensor = new RadiationSensorHandler(objects::RAD_SENSOR, objects::SPI_COM_IF, + spiCookieRadSensor, gpioComIF); + static_cast(radSensor); + // The radiation sensor ADC is powered by the 5V stack connector which should always be on + radSensor->setStartUpImmediately(); + // It's a simple sensor, so just to to normal mode immediately + radSensor->setToGoToNormalModeImmediately(); +#if OBSW_DEBUG_RAD_SENSOR == 1 + radSensor->enablePeriodicDataPrint(true); +#endif } -void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF *gpioComIF, SpiComIF* spiComIF) { - GpioCookie* gpioCookieSus = new GpioCookie(); - GpioCallback* susgpio = nullptr; +void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF, + PowerSwitchIF* pwrSwitcher) { + using namespace gpio; + GpioCookie* gpioCookieSus = new GpioCookie(); + GpioCallback* susgpio = nullptr; - susgpio = new GpioCallback("Chip select SUS 1", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_1, susgpio); - susgpio = new GpioCallback("Chip select SUS 2", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_2, susgpio); - susgpio = new GpioCallback("Chip select SUS 3", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_3, susgpio); - susgpio = new GpioCallback("Chip select SUS 4", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_4, susgpio); - susgpio = new GpioCallback("Chip select SUS 5", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_5, susgpio); - susgpio = new GpioCallback("Chip select SUS 6", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_6, susgpio); - susgpio = new GpioCallback("Chip select SUS 7", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_7, susgpio); - susgpio = new GpioCallback("Chip select SUS 8", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_8, susgpio); - susgpio = new GpioCallback("Chip select SUS 9", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_9, susgpio); - susgpio = new GpioCallback("Chip select SUS 10", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_10, susgpio); - susgpio = new GpioCallback("Chip select SUS 11", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_11, susgpio); - susgpio = new GpioCallback("Chip select SUS 12", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_12, susgpio); - susgpio = new GpioCallback("Chip select SUS 13", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieSus->addGpio(gpioIds::CS_SUS_13, susgpio); + susgpio = new GpioCallback("Chip select SUS 0", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_0, susgpio); + susgpio = new GpioCallback("Chip select SUS 1", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_1, susgpio); + susgpio = new GpioCallback("Chip select SUS 2", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_2, susgpio); + susgpio = new GpioCallback("Chip select SUS 3", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_3, susgpio); + susgpio = new GpioCallback("Chip select SUS 4", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_4, susgpio); + susgpio = new GpioCallback("Chip select SUS 5", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_5, susgpio); + susgpio = new GpioCallback("Chip select SUS 6", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_6, susgpio); + susgpio = new GpioCallback("Chip select SUS 7", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_7, susgpio); + susgpio = new GpioCallback("Chip select SUS 8", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_8, susgpio); + susgpio = new GpioCallback("Chip select SUS 9", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_9, susgpio); + susgpio = new GpioCallback("Chip select SUS 10", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_10, susgpio); + susgpio = new GpioCallback("Chip select SUS 11", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieSus->addGpio(gpioIds::CS_SUS_11, susgpio); - gpioComIF->addGpios(gpioCookieSus); + gpioComIF->addGpios(gpioCookieSus); - SpiCookie* spiCookieSus1 = new SpiCookie(addresses::SUS_1, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus2 = new SpiCookie(addresses::SUS_2, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus3 = new SpiCookie(addresses::SUS_3, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus4 = new SpiCookie(addresses::SUS_4, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus5 = new SpiCookie(addresses::SUS_5, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus6 = new SpiCookie(addresses::SUS_6, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus7 = new SpiCookie(addresses::SUS_7, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus8 = new SpiCookie(addresses::SUS_8, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus9 = new SpiCookie(addresses::SUS_9, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus10 = new SpiCookie(addresses::SUS_10, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus11 = new SpiCookie(addresses::SUS_11, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus12 = new SpiCookie(addresses::SUS_12, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); - SpiCookie* spiCookieSus13 = new SpiCookie(addresses::SUS_13, gpio::NO_GPIO, - std::string(q7s::SPI_DEFAULT_DEV), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - SUS::MAX1227_SPI_FREQ); + SusFdir* fdir = nullptr; + std::array susHandlers = {}; +#if OBSW_ADD_SUN_SENSORS == 1 + SpiCookie* spiCookie = + new SpiCookie(addresses::SUS_0, gpioIds::CS_SUS_0, q7s::SPI_DEFAULT_DEV, SUS::MAX_CMD_SIZE, + spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[0] = new SusHandler(objects::SUS_0, 0, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_0); + susHandlers[0]->setParent(objects::SUS_BOARD_ASS); + susHandlers[0]->setCustomFdir(fdir); - new SusHandler(objects::SUS_1, objects::SPI_COM_IF, spiCookieSus1, gpioComIF, - gpioIds::CS_SUS_1); - new SusHandler(objects::SUS_2, objects::SPI_COM_IF, spiCookieSus2, gpioComIF, - gpioIds::CS_SUS_2); - new SusHandler(objects::SUS_3, objects::SPI_COM_IF, spiCookieSus3, gpioComIF, - gpioIds::CS_SUS_3); - new SusHandler(objects::SUS_4, objects::SPI_COM_IF, spiCookieSus4, gpioComIF, - gpioIds::CS_SUS_4); - new SusHandler(objects::SUS_5, objects::SPI_COM_IF, spiCookieSus5, gpioComIF, - gpioIds::CS_SUS_5); - new SusHandler(objects::SUS_6, objects::SPI_COM_IF, spiCookieSus6, gpioComIF, - gpioIds::CS_SUS_6); - new SusHandler(objects::SUS_7, objects::SPI_COM_IF, spiCookieSus7, gpioComIF, - gpioIds::CS_SUS_7); - new SusHandler(objects::SUS_8, objects::SPI_COM_IF, spiCookieSus8, gpioComIF, - gpioIds::CS_SUS_8); - new SusHandler(objects::SUS_9, objects::SPI_COM_IF, spiCookieSus9, gpioComIF, - gpioIds::CS_SUS_9); - new SusHandler(objects::SUS_10, objects::SPI_COM_IF, spiCookieSus10, gpioComIF, - gpioIds::CS_SUS_10); - new SusHandler(objects::SUS_11, objects::SPI_COM_IF, spiCookieSus11, gpioComIF, - gpioIds::CS_SUS_11); - new SusHandler(objects::SUS_12, objects::SPI_COM_IF, spiCookieSus12, gpioComIF, - gpioIds::CS_SUS_12); - new SusHandler(objects::SUS_13, objects::SPI_COM_IF, spiCookieSus13, gpioComIF, - gpioIds::CS_SUS_13); + spiCookie = new SpiCookie(addresses::SUS_1, gpioIds::CS_SUS_1, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[1] = new SusHandler(objects::SUS_1, 1, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_1); + susHandlers[1]->setParent(objects::SUS_BOARD_ASS); + susHandlers[1]->setCustomFdir(fdir); + + spiCookie = new SpiCookie(addresses::SUS_2, gpioIds::CS_SUS_2, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[2] = new SusHandler(objects::SUS_2, 2, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_2); + susHandlers[2]->setParent(objects::SUS_BOARD_ASS); + susHandlers[2]->setCustomFdir(fdir); + + spiCookie = new SpiCookie(addresses::SUS_3, gpioIds::CS_SUS_3, std::string(q7s::SPI_DEFAULT_DEV), + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[3] = new SusHandler(objects::SUS_3, 3, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_3); + susHandlers[3]->setParent(objects::SUS_BOARD_ASS); + susHandlers[3]->setCustomFdir(fdir); + + spiCookie = new SpiCookie(addresses::SUS_4, gpioIds::CS_SUS_4, std::string(q7s::SPI_DEFAULT_DEV), + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[4] = new SusHandler(objects::SUS_4, 4, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_4); + susHandlers[4]->setParent(objects::SUS_BOARD_ASS); + susHandlers[4]->setCustomFdir(fdir); + + spiCookie = new SpiCookie(addresses::SUS_5, gpioIds::CS_SUS_5, std::string(q7s::SPI_DEFAULT_DEV), + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[5] = new SusHandler(objects::SUS_5, 5, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_5); + susHandlers[5]->setParent(objects::SUS_BOARD_ASS); + susHandlers[5]->setCustomFdir(fdir); + + spiCookie = new SpiCookie(addresses::SUS_6, gpioIds::CS_SUS_6, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[6] = new SusHandler(objects::SUS_6, 6, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_6); + susHandlers[6]->setParent(objects::SUS_BOARD_ASS); + susHandlers[6]->setCustomFdir(fdir); + + spiCookie = new SpiCookie(addresses::SUS_7, gpioIds::CS_SUS_7, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[7] = new SusHandler(objects::SUS_7, 7, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_7); + susHandlers[7]->setParent(objects::SUS_BOARD_ASS); + susHandlers[7]->setCustomFdir(fdir); + + spiCookie = new SpiCookie(addresses::SUS_8, gpioIds::CS_SUS_8, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[8] = new SusHandler(objects::SUS_8, 8, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_8); + susHandlers[8]->setParent(objects::SUS_BOARD_ASS); + susHandlers[8]->setCustomFdir(fdir); + + spiCookie = new SpiCookie(addresses::SUS_9, gpioIds::CS_SUS_9, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[9] = new SusHandler(objects::SUS_9, 9, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_9); + susHandlers[9]->setParent(objects::SUS_BOARD_ASS); + susHandlers[9]->setCustomFdir(fdir); + + spiCookie = new SpiCookie(addresses::SUS_10, gpioIds::CS_SUS_10, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[10] = new SusHandler(objects::SUS_10, 10, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_10); + susHandlers[10]->setParent(objects::SUS_BOARD_ASS); + susHandlers[10]->setCustomFdir(fdir); + + spiCookie = new SpiCookie(addresses::SUS_11, gpioIds::CS_SUS_11, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + susHandlers[11] = new SusHandler(objects::SUS_11, 11, objects::SPI_COM_IF, spiCookie); + fdir = new SusFdir(objects::SUS_11); + susHandlers[11]->setParent(objects::SUS_BOARD_ASS); + susHandlers[11]->setCustomFdir(fdir); + + for (auto& sus : susHandlers) { + if (sus != nullptr) { +#if OBSW_TEST_SUS == 1 + sus->setStartUpImmediately(); + sus->setToGoToNormalMode(true); +#endif +#if OBSW_DEBUG_SUS == 1 + sus->enablePeriodicPrintout(true, 3); +#endif + } + } + std::array susIds = {objects::SUS_0, objects::SUS_1, objects::SUS_2, + objects::SUS_3, objects::SUS_4, objects::SUS_5, + objects::SUS_6, objects::SUS_7, objects::SUS_8, + objects::SUS_9, objects::SUS_10, objects::SUS_11}; + SusAssHelper susAssHelper = SusAssHelper(susIds); + auto susAss = + new SusAssembly(objects::SUS_BOARD_ASS, objects::NO_OBJECT, pwrSwitcher, susAssHelper); + static_cast(susAss); +#endif /* OBSW_ADD_SUN_SENSORS == 1 */ } -void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF *gpioComIF, UartComIF* uartComIF) { - GpioCookie* gpioCookieAcsBoard = new GpioCookie(); +void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF, + PowerSwitchIF* pwrSwitcher) { + using namespace gpio; + GpioCookie* gpioCookieAcsBoard = new GpioCookie(); - std::stringstream consumer; - GpiodRegularByLineName* gpio = nullptr; - consumer << "0x" << std::hex << objects::GYRO_0_ADIS_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ADIS_CS, consumer.str(), - gpio::DIR_OUT, gpio::HIGH); - gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio); + std::stringstream consumer; + GpiodRegularByLineName* gpio = nullptr; + consumer << "0x" << std::hex << objects::GYRO_0_ADIS_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ADIS_CS, consumer.str(), Direction::OUT, + Levels::HIGH); + gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::GYRO_1_L3G_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, consumer.str(), gpio::DIR_OUT, - gpio::HIGH); - gpioCookieAcsBoard->addGpio(gpioIds::GYRO_1_L3G_CS, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::GYRO_1_L3G_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, consumer.str(), Direction::OUT, + Levels::HIGH); + gpioCookieAcsBoard->addGpio(gpioIds::GYRO_1_L3G_CS, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::GYRO_2_ADIS_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, consumer.str(), gpio::DIR_OUT, - gpio::HIGH); - gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_ADIS_CS, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::GYRO_2_ADIS_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, consumer.str(), Direction::OUT, + Levels::HIGH); + gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_ADIS_CS, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::GYRO_3_L3G_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, consumer.str(), gpio::DIR_OUT, - gpio::HIGH); - gpioCookieAcsBoard->addGpio(gpioIds::GYRO_3_L3G_CS, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::GYRO_3_L3G_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, consumer.str(), Direction::OUT, + Levels::HIGH); + gpioCookieAcsBoard->addGpio(gpioIds::GYRO_3_L3G_CS, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::MGM_0_LIS3_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, consumer.str(), gpio::DIR_OUT, - gpio::HIGH); - gpioCookieAcsBoard->addGpio(gpioIds::MGM_0_LIS3_CS, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::MGM_0_LIS3_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, consumer.str(), Direction::OUT, + Levels::HIGH); + gpioCookieAcsBoard->addGpio(gpioIds::MGM_0_LIS3_CS, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::MGM_1_RM3100_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, consumer.str(), gpio::DIR_OUT, - gpio::HIGH); - gpioCookieAcsBoard->addGpio(gpioIds::MGM_1_RM3100_CS, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::MGM_1_RM3100_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, consumer.str(), Direction::OUT, + Levels::HIGH); + gpioCookieAcsBoard->addGpio(gpioIds::MGM_1_RM3100_CS, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::MGM_2_LIS3_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, consumer.str(), - gpio::DIR_OUT, gpio::HIGH); - gpioCookieAcsBoard->addGpio(gpioIds::MGM_2_LIS3_CS, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::MGM_2_LIS3_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, consumer.str(), Direction::OUT, + Levels::HIGH); + gpioCookieAcsBoard->addGpio(gpioIds::MGM_2_LIS3_CS, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::MGM_3_RM3100_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_3_CS, consumer.str(), gpio::DIR_OUT, - gpio::HIGH); - gpioCookieAcsBoard->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::MGM_3_RM3100_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_3_CS, consumer.str(), Direction::OUT, + Levels::HIGH); + gpioCookieAcsBoard->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::GPS0_HANDLER; - // GNSS reset pins are active low - gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_0, consumer.str(), gpio::DIR_OUT, - gpio::HIGH); - gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_NRESET, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::GPS_CONTROLLER; + // GNSS reset pins are active low + gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_0, consumer.str(), Direction::OUT, + Levels::HIGH); + gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_NRESET, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::GPS1_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_1, consumer.str(), gpio::DIR_OUT, - gpio::HIGH); - gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_NRESET, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::GPS_CONTROLLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_1, consumer.str(), Direction::OUT, + Levels::HIGH); + gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_NRESET, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::GYRO_0_ADIS_HANDLER; - // Enable pins must be pulled low for regular operations - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, consumer.str(), - gpio::DIR_OUT, gpio::LOW); - gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ENABLE, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::GYRO_0_ADIS_HANDLER; + // Enable pins must be pulled low for regular operations + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, consumer.str(), Direction::OUT, + Levels::LOW); + gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ENABLE, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::GYRO_2_ADIS_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ENABLE, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_ENABLE, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::GYRO_2_ADIS_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ENABLE, consumer.str(), Direction::OUT, + Levels::LOW); + gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_ENABLE, gpio); - // Enable pins for GNSS - consumer.str(""); - consumer << "0x" << std::hex << objects::GPS0_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_0_ENABLE, consumer.str(), - gpio::DIR_OUT, gpio::LOW); - gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_ENABLE, gpio); + // Enable pins for GNSS + consumer.str(""); + consumer << "0x" << std::hex << objects::GPS_CONTROLLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_0_ENABLE, consumer.str(), Direction::OUT, + Levels::LOW); + gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_ENABLE, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::GPS1_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_1_ENABLE, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_ENABLE, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::GPS_CONTROLLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_1_ENABLE, consumer.str(), Direction::OUT, + Levels::LOW); + gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_ENABLE, gpio); - gpioComIF->addGpios(gpioCookieAcsBoard); + // Select pin. 0 for GPS side A, 1 for GPS side B + consumer.str(""); + consumer << "0x" << std::hex << objects::GPS_CONTROLLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_SELECT, consumer.str(), Direction::OUT, + Levels::LOW); + gpioCookieAcsBoard->addGpio(gpioIds::GNSS_SELECT, gpio); + gpioComIF->addGpios(gpioCookieAcsBoard); + AcsBoardFdir* fdir = nullptr; + static_cast(fdir); - std::string spiDev = q7s::SPI_DEFAULT_DEV; - SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev, - MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); - auto mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_0_LIS3_HANDLER, objects::SPI_COM_IF, - spiCookie, spi::LIS3_TRANSITION_DELAY); - mgmLis3Handler->setStartUpImmediately(); -#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 - mgmLis3Handler->setToGoToNormalMode(true); +#if OBSW_ADD_ACS_HANDLERS == 1 + std::string spiDev = q7s::SPI_DEFAULT_DEV; + SpiCookie* spiCookie = + new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev, + MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); + auto mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_0_LIS3_HANDLER, objects::SPI_COM_IF, + spiCookie, spi::LIS3_TRANSITION_DELAY); + fdir = new AcsBoardFdir(objects::MGM_0_LIS3_HANDLER); + mgmLis3Handler->setCustomFdir(fdir); + static_cast(mgmLis3Handler); +#if OBSW_TEST_ACS == 1 + mgmLis3Handler->setStartUpImmediately(); + mgmLis3Handler->setToGoToNormalMode(true); +#endif +#if OBSW_DEBUG_ACS == 1 + mgmLis3Handler->enablePeriodicPrintouts(true, 10); #endif - spiCookie = new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev, - RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); - auto mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_1_RM3100_HANDLER, objects::SPI_COM_IF, - spiCookie, spi::RM3100_TRANSITION_DELAY); - mgmRm3100Handler->setStartUpImmediately(); -#if FSFW_HAL_RM3100_MGM_DEBUG == 1 - mgmRm3100Handler->setToGoToNormalMode(true); + spiCookie = + new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev, + RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); + auto mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_1_RM3100_HANDLER, objects::SPI_COM_IF, + spiCookie, spi::RM3100_TRANSITION_DELAY); + fdir = new AcsBoardFdir(objects::MGM_1_RM3100_HANDLER); + mgmRm3100Handler->setCustomFdir(fdir); + mgmRm3100Handler->setParent(objects::ACS_BOARD_ASS); + static_cast(mgmRm3100Handler); +#if OBSW_TEST_ACS == 1 + mgmRm3100Handler->setStartUpImmediately(); + mgmRm3100Handler->setToGoToNormalMode(true); +#endif +#if OBSW_DEBUG_ACS == 1 + mgmRm3100Handler->enablePeriodicPrintouts(true, 10); #endif - spiCookie = new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, spiDev, - MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); - auto mgmLis3Handler2 = new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_COM_IF, - spiCookie, spi::LIS3_TRANSITION_DELAY); - mgmLis3Handler2->setStartUpImmediately(); -#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 - mgmLis3Handler2->setToGoToNormalMode(true); + spiCookie = + new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, spiDev, + MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); + mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_COM_IF, + spiCookie, spi::LIS3_TRANSITION_DELAY); + fdir = new AcsBoardFdir(objects::MGM_2_LIS3_HANDLER); + mgmLis3Handler->setCustomFdir(fdir); + mgmLis3Handler->setParent(objects::ACS_BOARD_ASS); + static_cast(mgmLis3Handler); +#if OBSW_TEST_ACS == 1 + mgmLis3Handler->setStartUpImmediately(); + mgmLis3Handler->setToGoToNormalMode(true); +#endif +#if OBSW_DEBUG_ACS == 1 + mgmLis3Handler->enablePeriodicPrintouts(true, 10); +#endif + spiCookie = + new SpiCookie(addresses::MGM_3_RM3100, gpioIds::MGM_3_RM3100_CS, spiDev, + RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); + mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_3_RM3100_HANDLER, objects::SPI_COM_IF, + spiCookie, spi::RM3100_TRANSITION_DELAY); + fdir = new AcsBoardFdir(objects::MGM_3_RM3100_HANDLER); + mgmRm3100Handler->setCustomFdir(fdir); + mgmRm3100Handler->setParent(objects::ACS_BOARD_ASS); +#if OBSW_TEST_ACS == 1 + mgmRm3100Handler->setStartUpImmediately(); + mgmRm3100Handler->setToGoToNormalMode(true); +#endif +#if OBSW_DEBUG_ACS == 1 + mgmRm3100Handler->enablePeriodicPrintouts(true, 10); #endif - spiCookie = new SpiCookie(addresses::MGM_3_RM3100, gpioIds::MGM_3_RM3100_CS, spiDev, - RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); - mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_3_RM3100_HANDLER, objects::SPI_COM_IF, - spiCookie, spi::RM3100_TRANSITION_DELAY); - mgmRm3100Handler->setStartUpImmediately(); -#if FSFW_HAL_RM3100_MGM_DEBUG == 1 - mgmRm3100Handler->setToGoToNormalMode(true); + // Commented until ACS board V2 in in clean room again + // Gyro 0 Side A + spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev, + ADIS1650X::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, + spi::DEFAULT_ADIS16507_SPEED); + auto adisHandler = new GyroADIS1650XHandler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, + spiCookie, ADIS1650X::Type::ADIS16505); + fdir = new AcsBoardFdir(objects::GYRO_0_ADIS_HANDLER); + adisHandler->setCustomFdir(fdir); + adisHandler->setParent(objects::ACS_BOARD_ASS); + static_cast(adisHandler); +#if OBSW_TEST_ACS == 1 + adisHandler->setStartUpImmediately(); + adisHandler->setToGoToNormalModeImmediately(); +#endif +#if OBSW_DEBUG_ACS == 1 + adisHandler->enablePeriodicPrintouts(true, 10); #endif - // Commented until ACS board V2 in in clean room again - // Gyro 0 Side A - spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev, - ADIS1650X::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, - spi::DEFAULT_ADIS16507_SPEED); - auto adisHandler = new GyroADIS1650XHandler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, - spiCookie, ADIS1650X::Type::ADIS16505); - adisHandler->setStartUpImmediately(); - // Gyro 1 Side A - spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev, - L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); - auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF, - spiCookie, spi::L3G_TRANSITION_DELAY); - gyroL3gHandler->setStartUpImmediately(); -#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1 - gyroL3gHandler->setToGoToNormalMode(true); + // Gyro 1 Side A + spiCookie = + new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev, L3GD20H::MAX_BUFFER_SIZE, + spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); + auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF, + spiCookie, spi::L3G_TRANSITION_DELAY); + fdir = new AcsBoardFdir(objects::GYRO_1_L3G_HANDLER); + gyroL3gHandler->setCustomFdir(fdir); + gyroL3gHandler->setParent(objects::ACS_BOARD_ASS); + static_cast(gyroL3gHandler); +#if OBSW_TEST_ACS == 1 + gyroL3gHandler->setStartUpImmediately(); + gyroL3gHandler->setToGoToNormalMode(true); #endif - // Gyro 2 Side B - spiCookie = new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev, - ADIS1650X::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, - spi::DEFAULT_ADIS16507_SPEED); - adisHandler = new GyroADIS1650XHandler(objects::GYRO_2_ADIS_HANDLER, objects::SPI_COM_IF, - spiCookie, ADIS1650X::Type::ADIS16505); - adisHandler->setStartUpImmediately(); - // Gyro 3 Side B - spiCookie = new SpiCookie(addresses::GYRO_3_L3G, gpioIds::GYRO_3_L3G_CS, spiDev, - L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); - gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_3_L3G_HANDLER, objects::SPI_COM_IF, - spiCookie, spi::L3G_TRANSITION_DELAY); - gyroL3gHandler->setStartUpImmediately(); -#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1 - gyroL3gHandler->setToGoToNormalMode(true); +#if OBSW_DEBUG_ACS == 1 + gyroL3gHandler->enablePeriodicPrintouts(true, 10); #endif - bool debugGps = false; + // Gyro 2 Side B + spiCookie = new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev, + ADIS1650X::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, + spi::DEFAULT_ADIS16507_SPEED); + adisHandler = new GyroADIS1650XHandler(objects::GYRO_2_ADIS_HANDLER, objects::SPI_COM_IF, + spiCookie, ADIS1650X::Type::ADIS16505); + fdir = new AcsBoardFdir(objects::GYRO_2_ADIS_HANDLER); + adisHandler->setCustomFdir(fdir); + adisHandler->setParent(objects::ACS_BOARD_ASS); +#if OBSW_TEST_ACS == 1 + adisHandler->setStartUpImmediately(); + adisHandler->setToGoToNormalModeImmediately(); +#endif + // Gyro 3 Side B + spiCookie = + new SpiCookie(addresses::GYRO_3_L3G, gpioIds::GYRO_3_L3G_CS, spiDev, L3GD20H::MAX_BUFFER_SIZE, + spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); + gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_3_L3G_HANDLER, objects::SPI_COM_IF, + spiCookie, spi::L3G_TRANSITION_DELAY); + fdir = new AcsBoardFdir(objects::GYRO_3_L3G_HANDLER); + gyroL3gHandler->setCustomFdir(fdir); + gyroL3gHandler->setParent(objects::ACS_BOARD_ASS); +#if OBSW_TEST_ACS == 1 + gyroL3gHandler->setStartUpImmediately(); + gyroL3gHandler->setToGoToNormalMode(true); +#endif +#if OBSW_DEBUG_ACS == 1 + gyroL3gHandler->enablePeriodicPrintouts(true, 10); +#endif + + bool debugGps = false; #if OBSW_DEBUG_GPS == 1 - debugGps = true; + debugGps = true; #endif - resetArgsGnss1.gnss1 = true; - resetArgsGnss1.gpioComIF = gpioComIF; - resetArgsGnss1.waitPeriodMs = 100; - resetArgsGnss0.gnss1 = false; - resetArgsGnss0.gpioComIF = gpioComIF; - resetArgsGnss0.waitPeriodMs = 100; - auto uartCookieGps0 = new UartCookie(objects::GPS0_HANDLER, q7s::UART_GNSS_DEV, - UartModes::CANONICAL, uart::GNSS_BAUD, uart::HYPERION_GPS_REPLY_MAX_BUFFER); - uartCookieGps0->setToFlushInput(true); - uartCookieGps0->setReadCycles(6); - auto gpsHandler0 = new GPSHyperionHandler(objects::GPS0_HANDLER, objects::UART_COM_IF, - uartCookieGps0, debugGps); - gpsHandler0->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss0); - gpsHandler0->setStartUpImmediately(); + resetArgsGnss1.gnss1 = true; + resetArgsGnss1.gpioComIF = gpioComIF; + resetArgsGnss1.waitPeriodMs = 100; + resetArgsGnss0.gnss1 = false; + resetArgsGnss0.gpioComIF = gpioComIF; + resetArgsGnss0.waitPeriodMs = 100; + auto gpsHandler0 = + new GPSHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps); + gpsHandler0->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss0); + + AcsBoardHelper acsBoardHelper = AcsBoardHelper( + objects::MGM_0_LIS3_HANDLER, objects::MGM_1_RM3100_HANDLER, objects::MGM_2_LIS3_HANDLER, + objects::MGM_3_RM3100_HANDLER, objects::GYRO_0_ADIS_HANDLER, objects::GYRO_1_L3G_HANDLER, + objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER); + auto acsAss = new AcsBoardAssembly(objects::ACS_BOARD_ASS, objects::NO_OBJECT, pwrSwitcher, + acsBoardHelper, gpioComIF); + static_cast(acsAss); +#if OBSW_TEST_ACS_BOARD_ASS == 1 + CommandMessage msg; + ModeMessage::setModeMessage(&msg, ModeMessage::CMD_MODE_COMMAND, DeviceHandlerIF::MODE_NORMAL, + duallane::A_SIDE); + ReturnValue_t result = MessageQueueSenderIF::sendMessage(acsAss->getCommandQueue(), &msg); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Sending mode command failed" << std::endl; + } +#endif +#endif /* OBSW_ADD_ACS_HANDLERS == 1 */ } void ObjectFactory::createHeaterComponents() { + using namespace gpio; + GpioCookie* heaterGpiosCookie = new GpioCookie; + GpiodRegularByLineName* gpio = nullptr; - GpioCookie* heaterGpiosCookie = new GpioCookie; - GpiodRegularByLineName* gpio = nullptr; + std::stringstream consumer; + consumer << "0x" << std::hex << objects::HEATER_HANDLER; + /* Pin H2-11 on stack connector */ + gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_0, consumer.str(), Direction::OUT, + Levels::LOW); + heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpio); + /* Pin H2-12 on stack connector */ + gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_1, consumer.str(), Direction::OUT, + Levels::LOW); + heaterGpiosCookie->addGpio(gpioIds::HEATER_1, gpio); - std::stringstream consumer; - consumer << "0x" << std::hex << objects::HEATER_HANDLER; - /* Pin H2-11 on stack connector */ - gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_0, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpio); - /* Pin H2-12 on stack connector */ - gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_1, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - heaterGpiosCookie->addGpio(gpioIds::HEATER_1, gpio); + /* Pin H2-13 on stack connector */ + gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_2, consumer.str(), Direction::OUT, + Levels::LOW); + heaterGpiosCookie->addGpio(gpioIds::HEATER_2, gpio); - /* Pin H2-13 on stack connector */ - gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_2, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - heaterGpiosCookie->addGpio(gpioIds::HEATER_2, gpio); + gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_3, consumer.str(), Direction::OUT, + Levels::LOW); + heaterGpiosCookie->addGpio(gpioIds::HEATER_3, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_3, consumer.str(), - gpio::DIR_OUT, gpio::LOW); - heaterGpiosCookie->addGpio(gpioIds::HEATER_3, gpio); + gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_4, consumer.str(), Direction::OUT, + Levels::LOW); + heaterGpiosCookie->addGpio(gpioIds::HEATER_4, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_4, consumer.str(), - gpio::DIR_OUT, gpio::LOW); - heaterGpiosCookie->addGpio(gpioIds::HEATER_4, gpio); + gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_5, consumer.str(), Direction::OUT, + Levels::LOW); + heaterGpiosCookie->addGpio(gpioIds::HEATER_5, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_5, consumer.str(), - gpio::DIR_OUT, gpio::LOW); - heaterGpiosCookie->addGpio(gpioIds::HEATER_5, gpio); + gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_6, consumer.str(), Direction::OUT, + Levels::LOW); + heaterGpiosCookie->addGpio(gpioIds::HEATER_6, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_6, consumer.str(), - gpio::DIR_OUT, gpio::LOW); - heaterGpiosCookie->addGpio(gpioIds::HEATER_6, gpio); + gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_7, consumer.str(), Direction::OUT, + Levels::LOW); + heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_7, consumer.str(), - gpio::DIR_OUT, gpio::LOW); - heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpio); - - new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, - objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN); + new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, + objects::PCDU_HANDLER, pcduSwitches::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V); } void ObjectFactory::createSolarArrayDeploymentComponents() { - GpioCookie* solarArrayDeplCookie = new GpioCookie; - GpiodRegularByLineName* gpio = nullptr; + using namespace gpio; + GpioCookie* solarArrayDeplCookie = new GpioCookie; + GpiodRegularByLineName* gpio = nullptr; - std::stringstream consumer; - consumer << "0x" << std::hex << objects::SOLAR_ARRAY_DEPL_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_0, - consumer.str(), gpio::DIR_OUT, gpio::LOW); - solarArrayDeplCookie->addGpio(gpioIds::DEPLSA1, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_1, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpio); + std::stringstream consumer; + consumer << "0x" << std::hex << objects::SOLAR_ARRAY_DEPL_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_0, consumer.str(), Direction::OUT, + Levels::LOW); + solarArrayDeplCookie->addGpio(gpioIds::DEPLSA1, gpio); + gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_1, consumer.str(), Direction::OUT, + Levels::LOW); + solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpio); - //TODO: Find out burn time. For now set to 1000 ms. - new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, objects::GPIO_IF, - solarArrayDeplCookie, objects::PCDU_HANDLER, pcduSwitches::DEPLOYMENT_MECHANISM, - gpioIds::DEPLSA1, gpioIds::DEPLSA2, 1000); + // TODO: Find out burn time. For now set to 1000 ms. + new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, objects::GPIO_IF, + solarArrayDeplCookie, objects::PCDU_HANDLER, + pcduSwitches::Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V, + gpioIds::DEPLSA1, gpioIds::DEPLSA2, 1000); } void ObjectFactory::createSyrlinksComponents() { - UartCookie* syrlinksUartCookie = new UartCookie(objects::SYRLINKS_HK_HANDLER, - q7s::UART_SYRLINKS_DEV, UartModes::NON_CANONICAL, uart::SYRLINKS_BAUD, - SYRLINKS::MAX_REPLY_SIZE); - syrlinksUartCookie->setParityEven(); + UartCookie* syrlinksUartCookie = + new UartCookie(objects::SYRLINKS_HK_HANDLER, q7s::UART_SYRLINKS_DEV, UartModes::NON_CANONICAL, + uart::SYRLINKS_BAUD, SYRLINKS::MAX_REPLY_SIZE); + syrlinksUartCookie->setParityEven(); - new SyrlinksHkHandler(objects::SYRLINKS_HK_HANDLER, objects::UART_COM_IF, syrlinksUartCookie); + new SyrlinksHkHandler(objects::SYRLINKS_HK_HANDLER, objects::UART_COM_IF, syrlinksUartCookie, + pcduSwitches::PDU1_CH1_SYRLINKS_12V); } -void ObjectFactory::createRtdComponents(LinuxLibgpioIF *gpioComIF) { - GpioCookie* rtdGpioCookie = new GpioCookie; +void ObjectFactory::createRtdComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher) { + using namespace gpio; + GpioCookie* rtdGpioCookie = new GpioCookie; - GpioCallback* gpioRtdIc0 = new GpioCallback("Chip select RTD IC0", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_3, gpioRtdIc0); - GpioCallback* gpioRtdIc1 = new GpioCallback("Chip select RTD IC1", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_4, gpioRtdIc1); - GpioCallback* gpioRtdIc2 = new GpioCallback("Chip select RTD IC2", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_5, gpioRtdIc2); - GpioCallback* gpioRtdIc3 = new GpioCallback("Chip select RTD IC3", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_6, gpioRtdIc3); - GpioCallback* gpioRtdIc4 = new GpioCallback("Chip select RTD IC4", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_7, gpioRtdIc4); - GpioCallback* gpioRtdIc5 = new GpioCallback("Chip select RTD IC5", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_8, gpioRtdIc5); - GpioCallback* gpioRtdIc6 = new GpioCallback("Chip select RTD IC6", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_9, gpioRtdIc6); - GpioCallback* gpioRtdIc7 = new GpioCallback("Chip select RTD IC7", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_10, gpioRtdIc7); - GpioCallback* gpioRtdIc8 = new GpioCallback("Chip select RTD IC8", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_11, gpioRtdIc8); - GpioCallback* gpioRtdIc9 = new GpioCallback("Chip select RTD IC9", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_12, gpioRtdIc9); - GpioCallback* gpioRtdIc10 = new GpioCallback("Chip select RTD IC10", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_13, gpioRtdIc10); - GpioCallback* gpioRtdIc11 = new GpioCallback("Chip select RTD IC11", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_14, gpioRtdIc11); - GpioCallback* gpioRtdIc12 = new GpioCallback("Chip select RTD IC12", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_15, gpioRtdIc12); - GpioCallback* gpioRtdIc13 = new GpioCallback("Chip select RTD IC13", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_16, gpioRtdIc13); - GpioCallback* gpioRtdIc14 = new GpioCallback("Chip select RTD IC14", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_17, gpioRtdIc14); - GpioCallback* gpioRtdIc15 = new GpioCallback("Chip select RTD IC15", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_18, gpioRtdIc15); + GpioCallback* gpioRtdIc0 = new GpioCallback("Chip select RTD IC0", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_3, gpioRtdIc0); + GpioCallback* gpioRtdIc1 = new GpioCallback("Chip select RTD IC1", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_4, gpioRtdIc1); + GpioCallback* gpioRtdIc2 = new GpioCallback("Chip select RTD IC2", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_5, gpioRtdIc2); + GpioCallback* gpioRtdIc3 = new GpioCallback("Chip select RTD IC3", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_6, gpioRtdIc3); + GpioCallback* gpioRtdIc4 = new GpioCallback("Chip select RTD IC4", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_7, gpioRtdIc4); + GpioCallback* gpioRtdIc5 = new GpioCallback("Chip select RTD IC5", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_8, gpioRtdIc5); + GpioCallback* gpioRtdIc6 = new GpioCallback("Chip select RTD IC6", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_9, gpioRtdIc6); + GpioCallback* gpioRtdIc7 = new GpioCallback("Chip select RTD IC7", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_10, gpioRtdIc7); + GpioCallback* gpioRtdIc8 = new GpioCallback("Chip select RTD IC8", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_11, gpioRtdIc8); + GpioCallback* gpioRtdIc9 = new GpioCallback("Chip select RTD IC9", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_12, gpioRtdIc9); + GpioCallback* gpioRtdIc10 = new GpioCallback("Chip select RTD IC10", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_13, gpioRtdIc10); + GpioCallback* gpioRtdIc11 = new GpioCallback("Chip select RTD IC11", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_14, gpioRtdIc11); + GpioCallback* gpioRtdIc12 = new GpioCallback("Chip select RTD IC12", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_15, gpioRtdIc12); + GpioCallback* gpioRtdIc13 = new GpioCallback("Chip select RTD IC13", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_16, gpioRtdIc13); + GpioCallback* gpioRtdIc14 = new GpioCallback("Chip select RTD IC14", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_17, gpioRtdIc14); + GpioCallback* gpioRtdIc15 = new GpioCallback("Chip select RTD IC15", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_18, gpioRtdIc15); - gpioComIF->addGpios(rtdGpioCookie); + gpioComIF->addGpios(rtdGpioCookie); - SpiCookie* spiRtdIc0 = new SpiCookie(addresses::RTD_IC_3, gpioIds::RTD_IC_3, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc1 = new SpiCookie(addresses::RTD_IC_4, gpioIds::RTD_IC_4, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc2 = new SpiCookie(addresses::RTD_IC_5, gpioIds::RTD_IC_5, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc3 = new SpiCookie(addresses::RTD_IC_6, gpioIds::RTD_IC_6, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc4 = new SpiCookie(addresses::RTD_IC_7, gpioIds::RTD_IC_7, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc5 = new SpiCookie(addresses::RTD_IC_8, gpioIds::RTD_IC_8, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc6 = new SpiCookie(addresses::RTD_IC_9, gpioIds::RTD_IC_9, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc7 = new SpiCookie(addresses::RTD_IC_10, gpioIds::RTD_IC_10, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, - spi::RTD_SPEED); - SpiCookie* spiRtdIc8 = new SpiCookie(addresses::RTD_IC_11, gpioIds::RTD_IC_11, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, - spi::RTD_SPEED); - SpiCookie* spiRtdIc9 = new SpiCookie(addresses::RTD_IC_12, gpioIds::RTD_IC_12, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, - spi::RTD_SPEED); - SpiCookie* spiRtdIc10 = new SpiCookie(addresses::RTD_IC_13, gpioIds::RTD_IC_13, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, - spi::RTD_SPEED); - SpiCookie* spiRtdIc11 = new SpiCookie(addresses::RTD_IC_14, gpioIds::RTD_IC_14, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, - spi::RTD_SPEED); - SpiCookie* spiRtdIc12 = new SpiCookie(addresses::RTD_IC_15, gpioIds::RTD_IC_15, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, - spi::RTD_SPEED); - SpiCookie* spiRtdIc13 = new SpiCookie(addresses::RTD_IC_16, gpioIds::RTD_IC_16, - std::string(q7s::SPI_DEFAULT_DEV), Max31865Definitions::MAX_REPLY_SIZE, - spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc14 = new SpiCookie(addresses::RTD_IC_17, gpioIds::RTD_IC_17, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, - spi::RTD_SPEED); - SpiCookie* spiRtdIc15 = new SpiCookie(addresses::RTD_IC_18, gpioIds::RTD_IC_18, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, - spi::RTD_SPEED); + static constexpr uint8_t NUMBER_RTDS = 16; +#if OBSW_ADD_RTD_DEVICES == 1 + std::array, NUMBER_RTDS> cookieArgs = {{ + {addresses::RTD_IC_3, gpioIds::RTD_IC_3}, + {addresses::RTD_IC_4, gpioIds::RTD_IC_4}, + {addresses::RTD_IC_5, gpioIds::RTD_IC_5}, + {addresses::RTD_IC_6, gpioIds::RTD_IC_6}, + {addresses::RTD_IC_7, gpioIds::RTD_IC_7}, + {addresses::RTD_IC_8, gpioIds::RTD_IC_8}, + {addresses::RTD_IC_9, gpioIds::RTD_IC_9}, + {addresses::RTD_IC_10, gpioIds::RTD_IC_10}, + {addresses::RTD_IC_11, gpioIds::RTD_IC_11}, + {addresses::RTD_IC_12, gpioIds::RTD_IC_12}, + {addresses::RTD_IC_13, gpioIds::RTD_IC_13}, + {addresses::RTD_IC_14, gpioIds::RTD_IC_14}, + {addresses::RTD_IC_15, gpioIds::RTD_IC_15}, + {addresses::RTD_IC_16, gpioIds::RTD_IC_16}, + {addresses::RTD_IC_17, gpioIds::RTD_IC_17}, + {addresses::RTD_IC_18, gpioIds::RTD_IC_18}, + }}; + std::array rtdIds = { + objects::RTD_IC_3, objects::RTD_IC_4, objects::RTD_IC_5, objects::RTD_IC_6, + objects::RTD_IC_7, objects::RTD_IC_8, objects::RTD_IC_9, objects::RTD_IC_10, + objects::RTD_IC_11, objects::RTD_IC_12, objects::RTD_IC_13, objects::RTD_IC_14, + objects::RTD_IC_15, objects::RTD_IC_16, objects::RTD_IC_17, objects::RTD_IC_18}; + std::array rtdCookies = {}; + std::array rtds = {}; + RtdFdir* rtdFdir = nullptr; + for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { + rtdCookies[idx] = + new SpiCookie(cookieArgs[idx].first, cookieArgs[idx].second, q7s::SPI_DEFAULT_DEV, + Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); + rtds[idx] = new Max31865PT1000Handler(rtdIds[idx], objects::SPI_COM_IF, rtdCookies[idx]); + rtds[idx]->setParent(objects::TCS_BOARD_ASS); + rtdFdir = new RtdFdir(rtdIds[idx]); + rtds[idx]->setCustomFdir(rtdFdir); + rtds[idx]->setDeviceIdx(idx + 3); + } - Max31865PT1000Handler* rtdIc0 = new Max31865PT1000Handler(objects::RTD_IC_3, objects::SPI_COM_IF, - spiRtdIc0); - Max31865PT1000Handler* rtdIc1 = new Max31865PT1000Handler(objects::RTD_IC_4, objects::SPI_COM_IF, - spiRtdIc1); - Max31865PT1000Handler* rtdIc2 = new Max31865PT1000Handler(objects::RTD_IC_5, objects::SPI_COM_IF, - spiRtdIc2); - Max31865PT1000Handler* rtdIc3 = new Max31865PT1000Handler(objects::RTD_IC_6, objects::SPI_COM_IF, - spiRtdIc3); - Max31865PT1000Handler* rtdIc4 = new Max31865PT1000Handler(objects::RTD_IC_7, objects::SPI_COM_IF, - spiRtdIc4); - Max31865PT1000Handler* rtdIc5 = new Max31865PT1000Handler(objects::RTD_IC_8, objects::SPI_COM_IF, - spiRtdIc5); - Max31865PT1000Handler* rtdIc6 = new Max31865PT1000Handler(objects::RTD_IC_9, objects::SPI_COM_IF, - spiRtdIc6); - Max31865PT1000Handler* rtdIc7 = new Max31865PT1000Handler(objects::RTD_IC_10, - objects::SPI_COM_IF, spiRtdIc7); - Max31865PT1000Handler* rtdIc8 = new Max31865PT1000Handler(objects::RTD_IC_11, - objects::SPI_COM_IF, spiRtdIc8); - Max31865PT1000Handler* rtdIc9 = new Max31865PT1000Handler(objects::RTD_IC_12, - objects::SPI_COM_IF, spiRtdIc9); - Max31865PT1000Handler* rtdIc10 = new Max31865PT1000Handler(objects::RTD_IC_13, - objects::SPI_COM_IF, spiRtdIc10); - Max31865PT1000Handler* rtdIc11 = new Max31865PT1000Handler(objects::RTD_IC_14, - objects::SPI_COM_IF, spiRtdIc11); - Max31865PT1000Handler* rtdIc12 = new Max31865PT1000Handler(objects::RTD_IC_15, - objects::SPI_COM_IF, spiRtdIc12); - Max31865PT1000Handler* rtdIc13 = new Max31865PT1000Handler(objects::RTD_IC_16, - objects::SPI_COM_IF, spiRtdIc13); - Max31865PT1000Handler* rtdIc14 = new Max31865PT1000Handler(objects::RTD_IC_17, - objects::SPI_COM_IF, spiRtdIc14); - Max31865PT1000Handler* rtdIc15 = new Max31865PT1000Handler(objects::RTD_IC_18, - objects::SPI_COM_IF, spiRtdIc15); +#if OBSW_TEST_RTD == 1 + for (auto& rtd : rtds) { + if (rtd != nullptr) { + rtd->setStartUpImmediately(); + rtd->setInstantNormal(true); + } + } +#endif // OBSW_TEST_RTD == 1 + TcsBoardHelper helper(rtdIds); + TcsBoardAssembly* tcsBoardAss = + new TcsBoardAssembly(objects::TCS_BOARD_ASS, objects::NO_OBJECT, pwrSwitcher, + pcduSwitches::Switches::PDU1_CH0_TCS_BOARD_3V3, helper); + static_cast(tcsBoardAss); +#endif // OBSW_ADD_RTD_DEVICES == 1 +} - rtdIc0->setStartUpImmediately(); - rtdIc1->setStartUpImmediately(); - rtdIc2->setStartUpImmediately(); -#if OBSW_DEBUG_RTD == 1 - rtdIc0->setInstantNormal(true); - rtdIc1->setInstantNormal(true); - rtdIc2->setInstantNormal(true); -#endif +void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF) { + using namespace gpio; + std::stringstream consumer; +#if OBSW_ADD_PLOC_MPSOC == 1 + consumer << "0x" << std::hex << objects::PLOC_MPSOC_HANDLER; + auto gpioConfigMPSoC = new GpiodRegularByLineName(q7s::gpioNames::ENABLE_MPSOC_UART, + consumer.str(), Direction::OUT, Levels::HIGH); + auto mpsocGpioCookie = new GpioCookie; + mpsocGpioCookie->addGpio(gpioIds::ENABLE_MPSOC_UART, gpioConfigMPSoC); + gpioComIF->addGpios(mpsocGpioCookie); + auto mpsocCookie = + new UartCookie(objects::PLOC_MPSOC_HANDLER, q7s::UART_PLOC_MPSOC_DEV, + UartModes::NON_CANONICAL, uart::PLOC_MPSOC_BAUD, mpsoc::MAX_REPLY_SIZE); + mpsocCookie->setNoFixedSizeReply(); + auto plocMpsocHelper = new PlocMPSoCHelper(objects::PLOC_MPSOC_HELPER); + new PlocMPSoCHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, mpsocCookie, + plocMpsocHelper, Gpio(gpioIds::ENABLE_MPSOC_UART, gpioComIF), + objects::PLOC_SUPERVISOR_HANDLER); +#endif /* OBSW_ADD_PLOC_MPSOC == 1 */ - static_cast(rtdIc0); - static_cast(rtdIc1); - static_cast(rtdIc2); - static_cast(rtdIc3); - static_cast(rtdIc4); - static_cast(rtdIc5); - static_cast(rtdIc6); - static_cast(rtdIc7); - static_cast(rtdIc8); - static_cast(rtdIc9); - static_cast(rtdIc10); - static_cast(rtdIc11); - static_cast(rtdIc12); - static_cast(rtdIc13); - static_cast(rtdIc14); - static_cast(rtdIc15); +#if OBSW_ADD_PLOC_SUPERVISOR == 1 + consumer << "0x" << std::hex << objects::PLOC_SUPERVISOR_HANDLER; + auto gpioConfigSupv = new GpiodRegularByLineName(q7s::gpioNames::ENABLE_SUPV_UART, consumer.str(), + Direction::OUT, Levels::HIGH); + auto supvGpioCookie = new GpioCookie; + supvGpioCookie->addGpio(gpioIds::ENABLE_SUPV_UART, gpioConfigSupv); + gpioComIF->addGpios(supvGpioCookie); + auto supervisorCookie = new UartCookie( + objects::PLOC_SUPERVISOR_HANDLER, q7s::UART_PLOC_SUPERVSIOR_DEV, UartModes::NON_CANONICAL, + uart::PLOC_SUPERVISOR_BAUD, supv::MAX_PACKET_SIZE * 20); + supervisorCookie->setNoFixedSizeReply(); + new PlocSupervisorHandler(objects::PLOC_SUPERVISOR_HANDLER, objects::UART_COM_IF, + supervisorCookie, Gpio(gpioIds::ENABLE_SUPV_UART, gpioComIF), + pcduSwitches::PDU1_CH6_PLOC_12V); +#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */ + static_cast(consumer); } void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF) { - GpioCookie* gpioCookieRw = new GpioCookie; - GpioCallback* csRw1 = new GpioCallback("Chip select reaction wheel 1", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieRw->addGpio(gpioIds::CS_RW1, csRw1); - GpioCallback* csRw2 = new GpioCallback("Chip select reaction wheel 2", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieRw->addGpio(gpioIds::CS_RW2, csRw2); - GpioCallback* csRw3 = new GpioCallback("Chip select reaction wheel 3", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieRw->addGpio(gpioIds::CS_RW3, csRw3); - GpioCallback* csRw4 = new GpioCallback("Chip select reaction wheel 4", gpio::DIR_OUT, gpio::HIGH, - &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - gpioCookieRw->addGpio(gpioIds::CS_RW4, csRw4); + using namespace gpio; + GpioCookie* gpioCookieRw = new GpioCookie; + GpioCallback* csRw1 = + new GpioCallback("Chip select reaction wheel 1", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieRw->addGpio(gpioIds::CS_RW1, csRw1); + GpioCallback* csRw2 = + new GpioCallback("Chip select reaction wheel 2", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieRw->addGpio(gpioIds::CS_RW2, csRw2); + GpioCallback* csRw3 = + new GpioCallback("Chip select reaction wheel 3", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieRw->addGpio(gpioIds::CS_RW3, csRw3); + GpioCallback* csRw4 = + new GpioCallback("Chip select reaction wheel 4", Direction::OUT, Levels::HIGH, + &gpioCallbacks::spiCsDecoderCallback, gpioComIF); + gpioCookieRw->addGpio(gpioIds::CS_RW4, csRw4); - std::stringstream consumer; - GpiodRegularByLineName* gpio = nullptr; - consumer << "0x" << std::hex << objects::RW1; - gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_1, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - gpioCookieRw->addGpio(gpioIds::EN_RW1, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::RW2; - gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_2, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - gpioCookieRw->addGpio(gpioIds::EN_RW2, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::RW3; - gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_3, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - gpioCookieRw->addGpio(gpioIds::EN_RW3, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::RW4; - gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_4, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - gpioCookieRw->addGpio(gpioIds::EN_RW4, gpio); + std::stringstream consumer; + GpiodRegularByLineName* gpio = nullptr; + consumer << "0x" << std::hex << objects::RW1; + gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_1, consumer.str(), Direction::OUT, + Levels::LOW); + gpioCookieRw->addGpio(gpioIds::EN_RW1, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::RW2; + gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_2, consumer.str(), Direction::OUT, + Levels::LOW); + gpioCookieRw->addGpio(gpioIds::EN_RW2, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::RW3; + gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_3, consumer.str(), Direction::OUT, + Levels::LOW); + gpioCookieRw->addGpio(gpioIds::EN_RW3, gpio); + consumer.str(""); + consumer << "0x" << std::hex << objects::RW4; + gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_4, consumer.str(), Direction::OUT, + Levels::LOW); + gpioCookieRw->addGpio(gpioIds::EN_RW4, gpio); - gpioComIF->addGpios(gpioCookieRw); + gpioComIF->addGpios(gpioCookieRw); - auto rw1SpiCookie = new SpiCookie(addresses::RW1, gpioIds::CS_RW1, q7s::SPI_RW_DEV, - RwDefinitions::MAX_REPLY_SIZE, spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, - nullptr); - auto rw2SpiCookie = new SpiCookie(addresses::RW2, gpioIds::CS_RW2, q7s::SPI_RW_DEV, - RwDefinitions::MAX_REPLY_SIZE, spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, - nullptr); - auto rw3SpiCookie = new SpiCookie(addresses::RW3, gpioIds::CS_RW3, q7s::SPI_RW_DEV, - RwDefinitions::MAX_REPLY_SIZE, spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, - nullptr); - auto rw4SpiCookie = new SpiCookie(addresses::RW4, gpioIds::CS_RW4, q7s::SPI_RW_DEV, - RwDefinitions::MAX_REPLY_SIZE, spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, - nullptr); +#if OBSW_ADD_RW == 1 + auto rw1SpiCookie = + new SpiCookie(addresses::RW1, gpioIds::CS_RW1, q7s::SPI_RW_DEV, RwDefinitions::MAX_REPLY_SIZE, + spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, nullptr); + auto rw2SpiCookie = + new SpiCookie(addresses::RW2, gpioIds::CS_RW2, q7s::SPI_RW_DEV, RwDefinitions::MAX_REPLY_SIZE, + spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, nullptr); + auto rw3SpiCookie = + new SpiCookie(addresses::RW3, gpioIds::CS_RW3, q7s::SPI_RW_DEV, RwDefinitions::MAX_REPLY_SIZE, + spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, nullptr); + auto rw4SpiCookie = + new SpiCookie(addresses::RW4, gpioIds::CS_RW4, q7s::SPI_RW_DEV, RwDefinitions::MAX_REPLY_SIZE, + spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, nullptr); - auto rwHandler1 = new RwHandler(objects::RW1, objects::SPI_COM_IF, rw1SpiCookie, gpioComIF, - gpioIds::EN_RW1); + auto rwHandler1 = + new RwHandler(objects::RW1, objects::SPI_COM_IF, rw1SpiCookie, gpioComIF, gpioIds::EN_RW1); #if OBSW_DEBUG_RW == 1 - rwHandler1->setStartUpImmediately(); + rwHandler1->setStartUpImmediately(); #endif - rw1SpiCookie->setCallbackArgs(rwHandler1); + rw1SpiCookie->setCallbackArgs(rwHandler1); + rwHandler1->setStartUpImmediately(); - auto rwHandler2 = new RwHandler(objects::RW2, objects::SPI_COM_IF, rw2SpiCookie, gpioComIF, - gpioIds::EN_RW2); + auto rwHandler2 = + new RwHandler(objects::RW2, objects::SPI_COM_IF, rw2SpiCookie, gpioComIF, gpioIds::EN_RW2); #if OBSW_DEBUG_RW == 1 - rwHandler2->setStartUpImmediately(); + rwHandler2->setStartUpImmediately(); #endif - rw2SpiCookie->setCallbackArgs(rwHandler2); + rw2SpiCookie->setCallbackArgs(rwHandler2); - auto rwHandler3 = new RwHandler(objects::RW3, objects::SPI_COM_IF, rw3SpiCookie, gpioComIF, - gpioIds::EN_RW3); + auto rwHandler3 = + new RwHandler(objects::RW3, objects::SPI_COM_IF, rw3SpiCookie, gpioComIF, gpioIds::EN_RW3); #if OBSW_DEBUG_RW == 1 - rwHandler3->setStartUpImmediately(); + rwHandler3->setStartUpImmediately(); #endif - rw3SpiCookie->setCallbackArgs(rwHandler3); + rw3SpiCookie->setCallbackArgs(rwHandler3); - auto rwHandler4 = new RwHandler(objects::RW4, objects::SPI_COM_IF, rw4SpiCookie, gpioComIF, - gpioIds::EN_RW4); + auto rwHandler4 = + new RwHandler(objects::RW4, objects::SPI_COM_IF, rw4SpiCookie, gpioComIF, gpioIds::EN_RW4); #if OBSW_DEBUG_RW == 1 - rwHandler4->setStartUpImmediately(); + rwHandler4->setStartUpImmediately(); #endif - rw4SpiCookie->setCallbackArgs(rwHandler4); + rw4SpiCookie->setCallbackArgs(rwHandler4); + +#endif /* OBSW_ADD_RW == 1 */ } -void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { - // GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core - GpioCookie* gpioCookiePtmeIp = new GpioCookie; - GpiodRegularByLineName* gpio = nullptr; - std::stringstream consumer; - consumer << "0x" << std::hex << objects::PAPB_VC0; - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC0, consumer.str()); - gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_BUSY, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::PAPB_VC0; - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, consumer.str()); - gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_EMPTY, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::PAPB_VC1; - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, consumer.str()); - gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_BUSY, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::PAPB_VC1; - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC1, consumer.str()); - gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_EMPTY, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::PAPB_VC2; - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC2, consumer.str()); - gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_BUSY, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::PAPB_VC2; - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC2, consumer.str()); - gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_EMPTY, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::PAPB_VC3; - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC3, consumer.str()); - gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::PAPB_VC3; - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, consumer.str()); - gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio); +void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) { + using namespace gpio; + // GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core + GpioCookie* gpioCookiePtmeIp = new GpioCookie; + GpiodRegularByLineName* gpio = nullptr; + std::stringstream consumer; + consumer.str("PAPB VC0"); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC0, consumer.str()); + gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_BUSY, gpio); + consumer.str("PAPB VC0"); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, consumer.str()); + gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_EMPTY, gpio); + consumer.str("PAPB VC 1"); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, consumer.str()); + gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_BUSY, gpio); + consumer.str(""); + consumer.str("PAPB VC 1"); + gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_EMPTY, gpio); + consumer.str(""); + consumer.str("PAPB VC 2"); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC2, consumer.str()); + gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_BUSY, gpio); + consumer.str(""); + consumer.str("PAPB VC 2"); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC2, consumer.str()); + gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_EMPTY, gpio); + consumer.str(""); + consumer.str("PAPB VC 3"); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC3, consumer.str()); + gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio); + consumer.str(""); + consumer.str("PAPB VC 3"); + gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, consumer.str()); + gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio); - gpioComIF->addGpios(gpioCookiePtmeIp); + gpioComIF->addGpios(gpioCookiePtmeIp); - // Creating virtual channel interfaces - VcInterfaceIF* vc0 = new PapbVcInterface(objects::PAPB_VC0, gpioComIF, gpioIds::VC0_PAPB_BUSY, - gpioIds::VC0_PAPB_EMPTY, PtmeConfig::VC0_OFFSETT); - VcInterfaceIF* vc1 = new PapbVcInterface(objects::PAPB_VC1, gpioComIF, gpioIds::VC1_PAPB_BUSY, - gpioIds::VC1_PAPB_EMPTY, PtmeConfig::VC1_OFFSETT); - VcInterfaceIF* vc2 = new PapbVcInterface(objects::PAPB_VC2, gpioComIF, gpioIds::VC2_PAPB_BUSY, - gpioIds::VC2_PAPB_EMPTY, PtmeConfig::VC2_OFFSETT); - VcInterfaceIF* vc3 = new PapbVcInterface(objects::PAPB_VC3, gpioComIF, gpioIds::VC3_PAPB_BUSY, - gpioIds::VC3_PAPB_EMPTY, PtmeConfig::VC3_OFFSETT); + // Creating virtual channel interfaces + VcInterfaceIF* vc0 = + new PapbVcInterface(gpioComIF, gpioIds::VC0_PAPB_BUSY, gpioIds::VC0_PAPB_EMPTY, q7s::UIO_PTME, + q7s::uiomapids::PTME_VC0); + VcInterfaceIF* vc1 = + new PapbVcInterface(gpioComIF, gpioIds::VC1_PAPB_BUSY, gpioIds::VC1_PAPB_EMPTY, q7s::UIO_PTME, + q7s::uiomapids::PTME_VC1); + VcInterfaceIF* vc2 = + new PapbVcInterface(gpioComIF, gpioIds::VC2_PAPB_BUSY, gpioIds::VC2_PAPB_EMPTY, q7s::UIO_PTME, + q7s::uiomapids::PTME_VC2); + VcInterfaceIF* vc3 = + new PapbVcInterface(gpioComIF, gpioIds::VC3_PAPB_BUSY, gpioIds::VC3_PAPB_EMPTY, q7s::UIO_PTME, + q7s::uiomapids::PTME_VC3); - // Creating ptme object and adding virtual channel interfaces - Ptme* ptme = new Ptme(objects::PTME); - ptme->addVcInterface(ccsds::VC0, vc0); - ptme->addVcInterface(ccsds::VC1, vc1); - ptme->addVcInterface(ccsds::VC2, vc2); - ptme->addVcInterface(ccsds::VC3, vc3); + // Creating ptme object and adding virtual channel interfaces + Ptme* ptme = new Ptme(objects::PTME); + ptme->addVcInterface(ccsds::VC0, vc0); + ptme->addVcInterface(ccsds::VC1, vc1); + ptme->addVcInterface(ccsds::VC2, vc2); + ptme->addVcInterface(ccsds::VC3, vc3); - GpioCookie* gpioCookieRateSetter = new GpioCookie; - consumer.str(""); - consumer << "ptme rate setter"; - // Init to low -> default bit rate is low bit rate (200 kbps in downlink with syrlinks) - gpio = new GpiodRegularByLineName(q7s::gpioNames::BIT_RATE_SEL, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - gpioCookieRateSetter->addGpio(gpioIds::BIT_RATE_SEL, gpio); - gpioComIF->addGpios(gpioCookieRateSetter); + AxiPtmeConfig* axiPtmeConfig = + new AxiPtmeConfig(objects::AXI_PTME_CONFIG, q7s::UIO_PTME, q7s::uiomapids::PTME_CONFIG); + PtmeConfig* ptmeConfig = new PtmeConfig(objects::PTME_CONFIG, axiPtmeConfig); +#if OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT == 1 + // Set to high value when not sending via syrlinks + static const uint32_t TRANSMITTER_TIMEOUT = 86400000; // 1 day +#else + static const uint32_t TRANSMITTER_TIMEOUT = 900000; // 15 minutes +#endif + CCSDSHandler* ccsdsHandler = new CCSDSHandler( + objects::CCSDS_HANDLER, objects::PTME, objects::CCSDS_PACKET_DISTRIBUTOR, ptmeConfig, + gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA, TRANSMITTER_TIMEOUT); - TxRateSetterIF* txRateSetterIF = new PtmeRateSetter(gpioIds::BIT_RATE_SEL, gpioComIF); + VirtualChannel* vc = nullptr; + vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE, objects::CCSDS_HANDLER); + ccsdsHandler->addVirtualChannel(ccsds::VC0, vc); + vc = new VirtualChannel(ccsds::VC1, common::VC1_QUEUE_SIZE, objects::CCSDS_HANDLER); + ccsdsHandler->addVirtualChannel(ccsds::VC1, vc); + vc = new VirtualChannel(ccsds::VC2, common::VC2_QUEUE_SIZE, objects::CCSDS_HANDLER); + ccsdsHandler->addVirtualChannel(ccsds::VC2, vc); + vc = new VirtualChannel(ccsds::VC3, common::VC3_QUEUE_SIZE, objects::CCSDS_HANDLER); + ccsdsHandler->addVirtualChannel(ccsds::VC3, vc); - CCSDSHandler* ccsdsHandler = new CCSDSHandler(objects::CCSDS_HANDLER, objects::PTME, - objects::CCSDS_PACKET_DISTRIBUTOR, txRateSetterIF, gpioComIF, - gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA); + GpioCookie* gpioCookiePdec = new GpioCookie; + consumer.str(""); + consumer << "0x" << std::hex << objects::PDEC_HANDLER; + // GPIO also low after linux boot (specified by device-tree) + gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, consumer.str(), Direction::OUT, + Levels::LOW); + gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio); - VirtualChannel* vc = nullptr; - vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE); - ccsdsHandler->addVirtualChannel(ccsds::VC0, vc); - vc = new VirtualChannel(ccsds::VC1, common::VC1_QUEUE_SIZE); - ccsdsHandler->addVirtualChannel(ccsds::VC1, vc); - vc = new VirtualChannel(ccsds::VC2, common::VC2_QUEUE_SIZE); - ccsdsHandler->addVirtualChannel(ccsds::VC2, vc); - vc = new VirtualChannel(ccsds::VC3, common::VC3_QUEUE_SIZE); - ccsdsHandler->addVirtualChannel(ccsds::VC3, vc); + gpioComIF->addGpios(gpioCookiePdec); - GpioCookie* gpioCookiePdec = new GpioCookie; - consumer.str(""); - consumer << "0x" << std::hex << objects::PDEC_HANDLER; - // GPIO also low after linux boot (specified by device-tree) - gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, consumer.str(), gpio::DIR_OUT, - gpio::LOW); - gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio); + new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET, + q7s::UIO_PDEC_CONFIG_MEMORY, q7s::UIO_PDEC_RAM, q7s::UIO_PDEC_REGISTERS); - gpioComIF->addGpios(gpioCookiePdec); + GpioCookie* gpioRS485Chip = new GpioCookie; + gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver", + Direction::OUT, Levels::LOW); + gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_CLOCK, gpio); + gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_DATA, "RS485 Transceiver", + Direction::OUT, Levels::LOW); + gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_DATA, gpio); - new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET, - std::string(q7s::UIO_PDEC_CONFIG_MEMORY), std::string(q7s::UIO_PDEC_RAM), - std::string(q7s::UIO_PDEC_REGISTERS)); + // Default configuration enables RX channels (RXEN = LOW) + gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_CLOCK, "RS485 Transceiver", + Direction::OUT, Levels::LOW); + gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_CLOCK, gpio); + gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_DATA, "RS485 Transceiver", + Direction::OUT, Levels::LOW); + gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_DATA, gpio); -#if BOARD_TE0720 == 0 - GpioCookie* gpioRS485Chip = new GpioCookie; - gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver", - gpio::Direction::DIR_OUT, gpio::LOW); - gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_CLOCK, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_DATA, "RS485 Transceiver", - gpio::Direction::DIR_OUT, gpio::LOW); - gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_DATA, gpio); + gpioComIF->addGpios(gpioRS485Chip); +} - // Default configuration enables RX channels (RXEN = LOW) - gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_CLOCK, "RS485 Transceiver", - gpio::Direction::DIR_OUT, gpio::LOW); - gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_CLOCK, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_DATA, "RS485 Transceiver", - gpio::Direction::DIR_OUT, gpio::LOW); - gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_DATA, gpio); +void ObjectFactory::createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF) { + using namespace gpio; + // Create all GPIO components first + GpioCookie* plPcduGpios = new GpioCookie; + GpiodRegularByLineName* gpio = nullptr; + std::string consumer; + // Switch pins are active high + consumer = "PLPCDU_ENB_VBAT_0"; + gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_VBAT0, consumer, Direction::OUT, + gpio::Levels::LOW); + plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_VBAT0, gpio); + consumer = "PLPCDU_ENB_VBAT_1"; + gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_VBAT1, consumer, Direction::OUT, + gpio::Levels::LOW); + plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_VBAT1, gpio); + consumer = "PLPCDU_ENB_DRO"; + gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_DRO, consumer, Direction::OUT, + gpio::Levels::LOW); + plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_DRO, gpio); + consumer = "PLPCDU_ENB_X8"; + gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_X8, consumer, Direction::OUT, + gpio::Levels::LOW); + plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_X8, gpio); + consumer = "PLPCDU_ENB_TX"; + gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_TX, consumer, Direction::OUT, + gpio::Levels::LOW); + plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_TX, gpio); + consumer = "PLPCDU_ENB_MPA"; + gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_MPA, consumer, Direction::OUT, + gpio::Levels::LOW); + plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_MPA, gpio); + consumer = "PLPCDU_ENB_HPA"; + gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_HPA, consumer, Direction::OUT, + gpio::Levels::LOW); + plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_HPA, gpio); - gpioComIF->addGpios(gpioRS485Chip); -#endif /* BOARD_TE0720 == 0 */ + // Chip select pin is active low + consumer = "PLPCDU_ADC_CS"; + gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ADC_CS, consumer, Direction::OUT, + gpio::Levels::HIGH); + plPcduGpios->addGpio(gpioIds::PLPCDU_ADC_CS, gpio); + gpioComIF->addGpios(plPcduGpios); + SpiCookie* spiCookie = new SpiCookie(addresses::PLPCDU_ADC, gpioIds::PLPCDU_ADC_CS, + q7s::SPI_DEFAULT_DEV, plpcdu::MAX_ADC_REPLY_SIZE, + spi::DEFAULT_MAX_1227_MODE, spi::PL_PCDU_MAX_1227_SPEED); + // Create device handler components + auto plPcduHandler = + new PayloadPcduHandler(objects::PLPCDU_HANDLER, objects::SPI_COM_IF, spiCookie, gpioComIF, + SdCardManager::instance(), false); + spiCookie->setCallbackMode(PayloadPcduHandler::extConvAsTwoCallback, plPcduHandler); +// plPcduHandler->enablePeriodicPrintout(true, 5); +// static_cast(plPcduHandler); +#if OBSW_TEST_PL_PCDU == 1 + plPcduHandler->setStartUpImmediately(); +#endif +#if OBSW_DEBUG_PL_PCDU == 1 + plPcduHandler->setToGoToNormalModeImmediately(true); + plPcduHandler->enablePeriodicPrintout(true, 10); +#endif } void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) { - -#if BOARD_TE0720 == 0 - new Q7STestTask(objects::TEST_TASK); -#endif - -#if BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1 -#if OBSW_TEST_GPIO_OPEN_BYLABEL == 1 - /* Configure MIO0 as input */ - GpiodRegular* testGpio = new GpiodRegular("MIO0", gpio::DIR_OUT, 0, "/amba_pl/gpio@41200000", 0); -#elif OBSW_TEST_GPIO_OPEN_BY_LINE_NAME - GpiodRegularByLineName* testGpio = new GpiodRegularByLineName("test-name", "gpio-test", - gpio::DIR_OUT, 0); -#else - /* Configure MIO0 as input */ - GpiodRegular* testGpio = new GpiodRegular("gpiochip0", 0, "MIO0", gpio::IN, 0); -#endif /* OBSW_TEST_GPIO_LABEL == 1 */ - GpioCookie* gpioCookie = new GpioCookie; - gpioCookie->addGpio(gpioIds::TEST_ID_0, testGpio); - new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); -#endif - -#if BOARD_TE0720 == 1 && OBSW_TEST_SUS_HANDLER == 1 - GpioCookie* gpioCookieSus = new GpioCookie; - GpiodRegular* chipSelectSus = new GpiodRegular(std::string("gpiochip1"), 9, - std::string("Chip Select Sus Sensor"), gpio::DIR_OUT, 1); - gpioCookieSus->addGpio(gpioIds::CS_SUS_1, chipSelectSus); - gpioComIF->addGpios(gpioCookieSus); - - SpiCookie* spiCookieSus = new SpiCookie(addresses::SUS_1, std::string("/dev/spidev1.0"), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::DEFAULT_MAX_1227_SPEED); - - new SusHandler(objects::SUS_1, objects::SPI_COM_IF, spiCookieSus, gpioComIF, - gpioIds::CS_SUS_1); -#endif - -#if BOARD_TE0720 == 1 && OBSW_TEST_CCSDS_BRIDGE == 1 - GpioCookie* gpioCookieCcsdsIp = new GpioCookie; - GpiodRegular* papbBusyN = new GpiodRegular(std::string("gpiochip0"), 0, std::string("PAPBBusy_VC0")); - gpioCookieCcsdsIp->addGpio(gpioIds::PAPB_BUSY_N, papbBusyN); - GpiodRegular* papbEmpty = new GpiodRegular(std::string("gpiochip0"), 1, - std::string("PAPBEmpty_VC0")); - gpioCookieCcsdsIp->addGpio(gpioIds::PAPB_EMPTY, papbEmpty); - gpioComIF->addGpios(gpioCookieCcsdsIp); - - new CCSDSIPCoreBridge(objects::CCSDS_IP_CORE_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR, - objects::TM_STORE, objects::TC_STORE, gpioComIF, std::string("/dev/uio0"), - gpioIds::PAPB_BUSY_N, gpioIds::PAPB_EMPTY); -#endif - -#if BOARD_TE0720 == 1 && OBSW_TEST_RADIATION_SENSOR_HANDLER == 1 - GpioCookie* gpioCookieRadSensor = new GpioCookie; - GpiodRegular* chipSelectRadSensor = new GpiodRegular(std::string("gpiochip1"), 0, - std::string("Chip select radiation sensor"), gpio::DIR_OUT, 1); - gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, chipSelectRadSensor); - gpioComIF->addGpios(gpioCookieRadSensor); - - SpiCookie* spiCookieRadSensor = new SpiCookie(addresses::RAD_SENSOR, gpioIds::CS_RAD_SENSOR, - std::string("/dev/spidev1.0"), SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, - spi::DEFAULT_MAX_1227_SPEED); - - RadiationSensorHandler* radSensor = new RadiationSensorHandler(objects::RAD_SENSOR, - objects::SPI_COM_IF, spiCookieRadSensor); - radSensor->setStartUpImmediately(); -#endif - -#if BOARD_TE0720 == 1 && OBSW_ADD_PLOC_MPSOC == 1 - UartCookie* plocUartCookie = new UartCookie(std::string("/dev/ttyPS1"), 115200, - PLOC_MPSOC::MAX_REPLY_SIZE); - /* Testing PlocMPSoCHandler on TE0720-03-1CFA */ - PlocMPSoCHandler* mpsocPlocHandler = new PlocMPSoCHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, - plocUartCookie); - mpsocPlocHandler->setStartUpImmediately(); -#endif - -#if BOARD_TE0720 == 1 && OBSW_TEST_TE7020_HEATER == 1 - /* Configuration for MIO0 on TE0720-03-1CFA */ - GpiodRegular* heaterGpio = new GpiodRegular(std::string("gpiochip0"), 0, std::string("MIO0"), gpio::IN, 0); - GpioCookie* gpioCookie = new GpioCookie; - gpioCookie->addGpio(gpioIds::HEATER_0, heaterGpio); - new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie, objects::PCDU_HANDLER, - pcduSwitches::TCS_BOARD_8V_HEATER_IN); -#endif - -#if BOARD_TE0720 == 1 && OBSW_ADD_PLOC_SUPERVISOR == 1 - /* Configuration for MIO0 on TE0720-03-1CFA */ - UartCookie* plocSupervisorCookie = new UartCookie(objects::PLOC_SUPERVISOR_HANDLER, - std::string("/dev/ttyPS1"), UartModes::NON_CANONICAL, 115200, - PLOC_SPV::MAX_PACKET_SIZE * 20); - plocSupervisorCookie->setNoFixedSizeReply(); - PlocSupervisorHandler* plocSupervisor = new PlocSupervisorHandler( - objects::PLOC_SUPERVISOR_HANDLER, objects::UART_COM_IF, plocSupervisorCookie); - plocSupervisor->setStartUpImmediately(); -#endif - + new Q7STestTask(objects::TEST_TASK); #if OBSW_ADD_SPI_TEST_CODE == 1 - new SpiTestClass(objects::SPI_TEST, gpioComIF); + new SpiTestClass(objects::SPI_TEST, gpioComIF); +#endif +#if OBSW_ADD_I2C_TEST_CODE == 1 + new I2cTestClass(objects::I2C_TEST, q7s::I2C_DEFAULT_DEV); +#endif +#if OBSW_ADD_UART_TEST_CODE == 1 + new UartTestClass(objects::UART_TEST); #endif - } diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index 0e723142..958e8f86 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -4,6 +4,8 @@ class LinuxLibgpioIF; class UartComIF; class SpiComIF; +class I2cComIF; +class PowerSwitchIF; namespace ObjectFactory { @@ -11,20 +13,24 @@ void setStatics(); void produce(void* args); void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF, - SpiComIF** spiComIF); + SpiComIF** spiComIF, I2cComIF** i2cComIF); +void createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher); +void createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF); void createTmpComponents(); -void createPcduComponents(); void createRadSensorComponent(LinuxLibgpioIF* gpioComIF); -void createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF); -void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF); +void createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF, + PowerSwitchIF* pwrSwitcher); +void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF, + PowerSwitchIF* pwrSwitcher); void createHeaterComponents(); void createSolarArrayDeploymentComponents(); void createSyrlinksComponents(); -void createRtdComponents(LinuxLibgpioIF* gpioComIF); +void createRtdComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher); +void createPayloadComponents(LinuxLibgpioIF* gpioComIF); void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF); -void createCcsdsComponents(LinuxLibgpioIF *gpioComIF); +void createCcsdsComponents(LinuxLibgpioIF* gpioComIF); void createTestComponents(LinuxLibgpioIF* gpioComIF); -}; +}; // namespace ObjectFactory #endif /* BSP_Q7S_OBJECTFACTORY_H_ */ diff --git a/bsp_q7s/core/ParameterHandler.cpp b/bsp_q7s/core/ParameterHandler.cpp index d6c8f34f..8cee046e 100644 --- a/bsp_q7s/core/ParameterHandler.cpp +++ b/bsp_q7s/core/ParameterHandler.cpp @@ -1,8 +1,5 @@ #include "ParameterHandler.h" -ParameterHandler::ParameterHandler(std::string mountPrefix): mountPrefix(mountPrefix) { -} +ParameterHandler::ParameterHandler(std::string mountPrefix) : mountPrefix(mountPrefix) {} -void ParameterHandler::setMountPrefix(std::string prefix) { - mountPrefix = prefix; -} +void ParameterHandler::setMountPrefix(std::string prefix) { mountPrefix = prefix; } diff --git a/bsp_q7s/core/ParameterHandler.h b/bsp_q7s/core/ParameterHandler.h index 81cbc099..4a108586 100644 --- a/bsp_q7s/core/ParameterHandler.h +++ b/bsp_q7s/core/ParameterHandler.h @@ -4,19 +4,17 @@ #include #include - - class ParameterHandler { -public: - ParameterHandler(std::string mountPrefix); + public: + ParameterHandler(std::string mountPrefix); - void setMountPrefix(std::string prefix); + void setMountPrefix(std::string prefix); - void setUpDummyParameter(); -private: - std::string mountPrefix; - DummyParameter dummyParam; + void setUpDummyParameter(); + + private: + std::string mountPrefix; + DummyParameter dummyParam; }; - #endif /* BSP_Q7S_CORE_PARAMETERHANDLER_H_ */ diff --git a/bsp_q7s/core/obsw.cpp b/bsp_q7s/core/obsw.cpp index e55d5652..aede1698 100644 --- a/bsp_q7s/core/obsw.cpp +++ b/bsp_q7s/core/obsw.cpp @@ -1,43 +1,45 @@ #include "obsw.h" -#include "OBSWVersion.h" -#include "OBSWConfig.h" -#include "InitMission.h" -#include "watchdogConf.h" -#include "fsfw/tasks/TaskFactory.h" -#include "fsfw/FSFWVersion.h" - -#include #include +#include + +#include "InitMission.h" +#include "OBSWConfig.h" +#include "OBSWVersion.h" +#include "fsfw/tasks/TaskFactory.h" +#include "fsfw/version.h" +#include "watchdogConf.h" static int OBSW_ALREADY_RUNNING = -2; int obsw::obsw() { - std::cout << "-- EIVE OBSW --" << std::endl; -#if BOARD_TE0720 == 0 - std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl; + using namespace fsfw; + std::cout << "-- EIVE OBSW --" << std::endl; +#ifdef TE0720_1CFA + std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl; #else - std::cout << "-- Compiled for Linux (TE0720) --" << std::endl; + std::cout << "-- Compiled for Linux (TE0720) --" << std::endl; #endif - std::cout << "-- OBSW v" << SW_VERSION << "." << SW_SUBVERSION << - "." << SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << "." << - FSFW_REVISION << "--" << std::endl; - std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; + std::cout << "-- OBSW v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_REVISION << ", FSFW v" + << FSFW_VERSION << "--" << std::endl; + std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; #if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1 - // Check special file here. This file is created or deleted by the eive-watchdog application - // or systemd service! - if(std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { - sif::warning << "File " << watchdog::RUNNING_FILE_NAME << " exists so the software might " - "already be running. Aborting.." << std::endl; - return OBSW_ALREADY_RUNNING; - } + // Check special file here. This file is created or deleted by the eive-watchdog application + // or systemd service! + if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { + sif::warning << "File " << watchdog::RUNNING_FILE_NAME + << " exists so the software might " + "already be running. Check if obsw systemd service has been stopped." + << std::endl; + return OBSW_ALREADY_RUNNING; + } #endif - initmission::initMission(); + initmission::initMission(); - for(;;) { - /* Suspend main thread by sleeping it. */ - TaskFactory::delayTask(5000); - } - return 0; + for (;;) { + /* Suspend main thread by sleeping it. */ + TaskFactory::delayTask(5000); + } + return 0; } diff --git a/bsp_q7s/devices/CMakeLists.txt b/bsp_q7s/devices/CMakeLists.txt deleted file mode 100644 index 70705e83..00000000 --- a/bsp_q7s/devices/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -target_sources(${TARGET_NAME} PRIVATE - PlocSupervisorHandler.cpp - PlocUpdater.cpp - PlocMemoryDumper.cpp -) - -add_subdirectory(startracker) \ No newline at end of file diff --git a/bsp_q7s/devices/PlocMemoryDumper.cpp b/bsp_q7s/devices/PlocMemoryDumper.cpp deleted file mode 100644 index cc4361bb..00000000 --- a/bsp_q7s/devices/PlocMemoryDumper.cpp +++ /dev/null @@ -1,206 +0,0 @@ -#include -#include "fsfw/ipc/QueueFactory.h" -#include "PlocMemoryDumper.h" - -#include -#include -#include - -PlocMemoryDumper::PlocMemoryDumper(object_id_t objectId) : - SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) { - commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); -} - -PlocMemoryDumper::~PlocMemoryDumper() { -} - -ReturnValue_t PlocMemoryDumper::initialize() { - - ReturnValue_t result = SystemObject::initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = commandActionHelper.initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = actionHelper.initialize(commandQueue); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t PlocMemoryDumper::performOperation(uint8_t operationCode) { - readCommandQueue(); - doStateMachine(); - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t PlocMemoryDumper::executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { - - if (state != State::IDLE) { - return IS_BUSY; - } - - switch (actionId) { - case DUMP_MRAM: { - size_t deserializeSize = sizeof(mram.startAddress) + sizeof(mram.endAddress); - SerializeAdapter::deSerialize(&mram.startAddress, &data, &deserializeSize, - SerializeIF::Endianness::BIG); - SerializeAdapter::deSerialize(&mram.endAddress, &data, &deserializeSize, - SerializeIF::Endianness::BIG); - if (mram.endAddress > MAX_MRAM_ADDRESS) { - return MRAM_ADDRESS_TOO_HIGH; - } - if (mram.endAddress <= mram.startAddress) { - return MRAM_INVALID_ADDRESS_COMBINATION; - } - state = State::COMMAND_FIRST_MRAM_DUMP; - break; - } - default: { - sif::warning << "PlocMemoryDumper::executeAction: Received command with invalid action id" - << std::endl; - return INVALID_ACTION_ID; - } - } - - return EXECUTION_FINISHED; -} - -MessageQueueId_t PlocMemoryDumper::getCommandQueue() const { - return commandQueue->getId(); -} - -MessageQueueIF* PlocMemoryDumper::getCommandQueuePtr() { - return commandQueue; -} - -void PlocMemoryDumper::readCommandQueue() { - CommandMessage message; - ReturnValue_t result; - - for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK; - result = commandQueue->receiveMessage(&message)) { - if (result != RETURN_OK) { - continue; - } - result = actionHelper.handleActionMessage(&message); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; - } - - result = commandActionHelper.handleReply(&message); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; - } - - sif::debug << "PlocMemoryDumper::readCommandQueue: Received message with invalid format" - << std::endl; - } -} - -void PlocMemoryDumper::doStateMachine() { - switch (state) { - case State::IDLE: - break; - case State::COMMAND_FIRST_MRAM_DUMP: - commandNextMramDump(PLOC_SPV::FIRST_MRAM_DUMP); - break; - case State::COMMAND_CONSECUTIVE_MRAM_DUMP: - commandNextMramDump(PLOC_SPV::CONSECUTIVE_MRAM_DUMP); - break; - case State::EXECUTING_MRAM_DUMP: - break; - default: - sif::debug << "PlocMemoryDumper::doStateMachine: Invalid state" << std::endl; - break; - } -} - -void PlocMemoryDumper::stepSuccessfulReceived(ActionId_t actionId, - uint8_t step) { -} - -void PlocMemoryDumper::stepFailedReceived(ActionId_t actionId, uint8_t step, - ReturnValue_t returnCode) { -} - -void PlocMemoryDumper::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) { - -} - -void PlocMemoryDumper::completionSuccessfulReceived(ActionId_t actionId) { - switch (pendingCommand) { - case (PLOC_SPV::FIRST_MRAM_DUMP): - case (PLOC_SPV::CONSECUTIVE_MRAM_DUMP): - if (mram.endAddress == mram.startAddress) { - triggerEvent(MRAM_DUMP_FINISHED); - state = State::IDLE; - } - else { - state = State::COMMAND_CONSECUTIVE_MRAM_DUMP; - } - break; - default: - sif::debug << "PlocMemoryDumper::completionSuccessfulReceived: Invalid pending command" - << std::endl; - state = State::IDLE; - break; - } -} - -void PlocMemoryDumper::completionFailedReceived(ActionId_t actionId, - ReturnValue_t returnCode) { - switch(pendingCommand) { - case(PLOC_SPV::FIRST_MRAM_DUMP): - case(PLOC_SPV::CONSECUTIVE_MRAM_DUMP): - triggerEvent(MRAM_DUMP_FAILED, mram.lastStartAddress); - break; - default: - sif::debug << "PlocMemoryDumper::completionFailedReceived: Invalid pending command " - << std::endl; - break; - } - state = State::IDLE; -} - -void PlocMemoryDumper::commandNextMramDump(ActionId_t dumpCommand) { - ReturnValue_t result = RETURN_OK; - - uint32_t tempStartAddress = 0; - uint32_t tempEndAddress = 0; - - if (mram.endAddress - mram.startAddress > MAX_MRAM_DUMP_SIZE) { - tempStartAddress = mram.startAddress; - tempEndAddress = mram.startAddress + MAX_MRAM_DUMP_SIZE; - mram.startAddress += MAX_MRAM_DUMP_SIZE; - mram.lastStartAddress = tempStartAddress; - } - else { - tempStartAddress = mram.startAddress; - tempEndAddress = mram.endAddress; - mram.startAddress = mram.endAddress; - } - - MemoryParams params(tempStartAddress, tempEndAddress); - - result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, - dumpCommand, ¶ms); - if (result != RETURN_OK) { - sif::warning << "PlocMemoryDumper::commandNextMramDump: Failed to send mram dump command " - << "with start address " << tempStartAddress << " and end address " - << tempEndAddress << std::endl; - triggerEvent(SEND_MRAM_DUMP_FAILED, result, tempStartAddress); - state = State::IDLE; - pendingCommand = NONE; - return; - } - state = State::EXECUTING_MRAM_DUMP; - pendingCommand = dumpCommand; - return; -} - diff --git a/bsp_q7s/devices/PlocMemoryDumper.h b/bsp_q7s/devices/PlocMemoryDumper.h deleted file mode 100644 index 72b031ae..00000000 --- a/bsp_q7s/devices/PlocMemoryDumper.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef MISSION_DEVICES_PLOCMEMORYDUMPER_H_ -#define MISSION_DEVICES_PLOCMEMORYDUMPER_H_ - -#include -#include -#include "OBSWConfig.h" -#include "fsfw/action/CommandActionHelper.h" -#include "fsfw/action/ActionHelper.h" -#include "fsfw/action/HasActionsIF.h" -#include "fsfw/action/CommandsActionsIF.h" -#include "fsfw/returnvalues/HasReturnvaluesIF.h" -#include "fsfw/tasks/ExecutableObjectIF.h" -#include "fsfw/objectmanager/SystemObject.h" -#include "bsp_q7s/memory/SdCardManager.h" -#include "linux/fsfwconfig/objects/systemObjectList.h" -#include "fsfw/tmtcpacket/SpacePacket.h" - - -/** - * @brief Because the buffer of the linux tty driver is limited to 2 x 65535 bytes, this class is - * created to perform large dumps of PLOC memories. - * - * @details Currently the PLOC supervisor only implements the functionality to dump the MRAM. - * - * @author J. Meier - */ -class PlocMemoryDumper : public SystemObject, - public HasActionsIF, - public ExecutableObjectIF, - public HasReturnvaluesIF, - public CommandsActionsIF { -public: - - static const ActionId_t NONE = 0; - static const ActionId_t DUMP_MRAM = 1; - - PlocMemoryDumper(object_id_t objectId); - virtual ~PlocMemoryDumper(); - - ReturnValue_t performOperation(uint8_t operationCode = 0) override; - ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, - const uint8_t* data, size_t size); - MessageQueueId_t getCommandQueue() const; - ReturnValue_t initialize() override; - MessageQueueIF* getCommandQueuePtr() override; - void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override; - void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override; - void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override; - void completionSuccessfulReceived(ActionId_t actionId) override; - void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override; - -private: - - static const uint32_t QUEUE_SIZE = 10; - - static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MEMORY_DUMPER; - - //! [EXPORT] : [COMMENT] The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000. - static const ReturnValue_t MRAM_ADDRESS_TOO_HIGH = MAKE_RETURN_CODE(0xA0); - //! [EXPORT] : [COMMENT] The specified end address is lower than the start address - static const ReturnValue_t MRAM_INVALID_ADDRESS_COMBINATION = MAKE_RETURN_CODE(0xA1); - - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MEMORY_DUMPER; - - //! [EXPORT] : [COMMENT] Failed to send mram dump command to supervisor handler - //! P1: Return value of commandAction function - //! P2: Start address of MRAM to dump with this command - static const Event SEND_MRAM_DUMP_FAILED = MAKE_EVENT(0, severity::LOW); - //! [EXPORT] : [COMMENT] Received completion failure report form PLOC supervisor handler - //! P1: MRAM start address of failing dump command - static const Event MRAM_DUMP_FAILED = MAKE_EVENT(1, severity::LOW); - //! [EXPORT] : [COMMENT] MRAM dump finished successfully - static const Event MRAM_DUMP_FINISHED = MAKE_EVENT(2, severity::LOW); - - // Maximum size of mram dump which can be retrieved with one command - static const uint32_t MAX_MRAM_DUMP_SIZE = 100000; - static const uint32_t MAX_MRAM_ADDRESS = 0x7d000; - - MessageQueueIF* commandQueue = nullptr; - - CommandActionHelper commandActionHelper; - - ActionHelper actionHelper; - - enum class State: uint8_t { - IDLE, - COMMAND_FIRST_MRAM_DUMP, - COMMAND_CONSECUTIVE_MRAM_DUMP, - EXECUTING_MRAM_DUMP - }; - - State state = State::IDLE; - - ActionId_t pendingCommand = NONE; - - typedef struct MemoryInfo { - // Stores the start address of the next memory range to dump - uint32_t startAddress; - uint32_t endAddress; - // Stores the start address of the last sent dump command - uint32_t lastStartAddress; - } MemoryInfo_t; - - MemoryInfo_t mram = {0, 0, 0}; - - void readCommandQueue(); - void doStateMachine(); - - /** - * @brief Sends the next mram dump command to the PLOC supervisor handler. - */ - void commandNextMramDump(ActionId_t dumpCommand); -}; - -#endif /* MISSION_DEVICES_PLOCMEMORYDUMPER_H_ */ diff --git a/bsp_q7s/devices/PlocSupervisorHandler.cpp b/bsp_q7s/devices/PlocSupervisorHandler.cpp deleted file mode 100644 index 30ea9572..00000000 --- a/bsp_q7s/devices/PlocSupervisorHandler.cpp +++ /dev/null @@ -1,1530 +0,0 @@ -#include -#include -#include -#include - -#include "PlocSupervisorHandler.h" -#include "OBSWConfig.h" - -#include -#include -#include - -PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, object_id_t uartComIFid, - CookieIF * comCookie) : - DeviceHandlerBase(objectId, uartComIFid, comCookie), hkset(this), bootStatusReport(this), latchupStatusReport( - this) { - if (comCookie == NULL) { - sif::error << "PlocSupervisorHandler: Invalid com cookie" << std::endl; - } -} - -PlocSupervisorHandler::~PlocSupervisorHandler() { -} - -ReturnValue_t PlocSupervisorHandler::initialize() { - ReturnValue_t result = RETURN_OK; - result = DeviceHandlerBase::initialize(); - if (result != RETURN_OK) { - return result; - } - uartComIf = dynamic_cast(communicationInterface); - if (uartComIf == nullptr) { - sif::warning << "PlocSupervisorHandler::initialize: Invalid uart com if" << std::endl; - return INVALID_UART_COM_IF; - } - -#if BOARD_TE0720 == 0 - sdcMan = SdCardManager::instance(); -#endif /* BOARD_TE0720 == 0 */ - - return result; -} - - -void PlocSupervisorHandler::doStartUp(){ -#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1 - setMode(MODE_NORMAL); -#else - setMode(_MODE_TO_ON); -#endif -} - -void PlocSupervisorHandler::doShutDown(){ - setMode(_MODE_POWER_DOWN); -} - -ReturnValue_t PlocSupervisorHandler::buildNormalDeviceCommand( - DeviceCommandId_t * id) { - return NOTHING_TO_SEND; -} - -ReturnValue_t PlocSupervisorHandler::buildTransitionDeviceCommand( - DeviceCommandId_t * id){ - return NOTHING_TO_SEND; -} - -ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( - DeviceCommandId_t deviceCommand, const uint8_t * commandData, - size_t commandDataLen) { - ReturnValue_t result = RETURN_FAILED; - switch(deviceCommand) { - case(PLOC_SPV::GET_HK_REPORT): { - prepareEmptyCmd(PLOC_SPV::APID_GET_HK_REPORT); - result = RETURN_OK; - break; - } - case(PLOC_SPV::RESTART_MPSOC): { - prepareEmptyCmd(PLOC_SPV::APID_RESTART_MPSOC); - result = RETURN_OK; - break; - } - case(PLOC_SPV::START_MPSOC): { - prepareEmptyCmd(PLOC_SPV::APID_START_MPSOC); - result = RETURN_OK; - break; - } - case(PLOC_SPV::SHUTDOWN_MPSOC): { - prepareEmptyCmd(PLOC_SPV::APID_SHUTWOWN_MPSOC); - result = RETURN_OK; - break; - } - case(PLOC_SPV::SEL_MPSOC_BOOT_IMAGE): { - prepareSelBootImageCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::RESET_MPSOC): { - prepareEmptyCmd(PLOC_SPV::APID_RESET_MPSOC); - result = RETURN_OK; - break; - } - case(PLOC_SPV::SET_TIME_REF): { - result = prepareSetTimeRefCmd(); - break; - } - case(PLOC_SPV::SET_BOOT_TIMEOUT): { - prepareSetBootTimeoutCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::SET_MAX_RESTART_TRIES): { - prepareRestartTriesCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::DISABLE_PERIOIC_HK_TRANSMISSION): { - prepareDisableHk(); - result = RETURN_OK; - break; - } - case(PLOC_SPV::GET_BOOT_STATUS_REPORT): { - prepareEmptyCmd(PLOC_SPV::APID_GET_BOOT_STATUS_RPT); - result = RETURN_OK; - break; - } - case(PLOC_SPV::WATCHDOGS_ENABLE): { - prepareWatchdogsEnableCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT): { - result = prepareWatchdogsConfigTimeoutCmd(commandData); - break; - } - case(PLOC_SPV::ENABLE_LATCHUP_ALERT): { - result = prepareLatchupConfigCmd(commandData, deviceCommand); - break; - } - case(PLOC_SPV::DISABLE_LATCHUP_ALERT): { - result = prepareLatchupConfigCmd(commandData, deviceCommand); - break; - } - case(PLOC_SPV::AUTO_CALIBRATE_ALERT): { - result = prepareAutoCalibrateAlertCmd(commandData); - break; - } - case(PLOC_SPV::SET_ALERT_LIMIT): { - result = prepareSetAlertLimitCmd(commandData); - break; - } - case(PLOC_SPV::SET_ALERT_IRQ_FILTER): { - result = prepareSetAlertIrqFilterCmd(commandData); - break; - } - case(PLOC_SPV::SET_ADC_SWEEP_PERIOD): { - result = prepareSetAdcSweetPeriodCmd(commandData); - break; - } - case(PLOC_SPV::SET_ADC_ENABLED_CHANNELS): { - prepareSetAdcEnabledChannelsCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::SET_ADC_WINDOW_AND_STRIDE): { - prepareSetAdcWindowAndStrideCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::SET_ADC_THRESHOLD): { - prepareSetAdcThresholdCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::GET_LATCHUP_STATUS_REPORT): { - prepareEmptyCmd(PLOC_SPV::APID_GET_LATCHUP_STATUS_REPORT); - result = RETURN_OK; - break; - } - case(PLOC_SPV::COPY_ADC_DATA_TO_MRAM): { - prepareEmptyCmd(PLOC_SPV::APID_COPY_ADC_DATA_TO_MRAM); - result = RETURN_OK; - break; - } - case(PLOC_SPV::ENABLE_NVMS): { - prepareEnableNvmsCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::SELECT_NVM): { - prepareSelectNvmCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::RUN_AUTO_EM_TESTS): { - result = prepareRunAutoEmTest(commandData); - break; - } - case(PLOC_SPV::WIPE_MRAM): { - result = prepareWipeMramCmd(commandData); - break; - } - case(PLOC_SPV::FIRST_MRAM_DUMP): - case(PLOC_SPV::CONSECUTIVE_MRAM_DUMP): - result = prepareDumpMramCmd(commandData); - break; - case(PLOC_SPV::PRINT_CPU_STATS): { - preparePrintCpuStatsCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::SET_DBG_VERBOSITY): { - prepareSetDbgVerbosityCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::CAN_LOOPBACK_TEST): { - prepareEmptyCmd(PLOC_SPV::APID_CAN_LOOPBACK_TEST); - result = RETURN_OK; - break; - } - case(PLOC_SPV::SET_GPIO): { - prepareSetGpioCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::READ_GPIO): { - prepareReadGpioCmd(commandData); - result = RETURN_OK; - break; - } - case(PLOC_SPV::RESTART_SUPERVISOR): { - prepareEmptyCmd(PLOC_SPV::APID_RESTART_SUPERVISOR); - result = RETURN_OK; - break; - } - case(PLOC_SPV::FACTORY_RESET_CLEAR_ALL): { - PLOC_SPV::FactoryReset packet(PLOC_SPV::FactoryReset::Op::CLEAR_ALL); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - result = RETURN_OK; - break; - } - case(PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR): { - PLOC_SPV::FactoryReset packet(PLOC_SPV::FactoryReset::Op::MIRROR_ENTRIES); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - result = RETURN_OK; - break; - } - case(PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR): { - PLOC_SPV::FactoryReset packet(PLOC_SPV::FactoryReset::Op::CIRCULAR_ENTRIES); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - result = RETURN_OK; - break; - } - case(PLOC_SPV::UPDATE_AVAILABLE): - case(PLOC_SPV::UPDATE_IMAGE_DATA): - case(PLOC_SPV::UPDATE_VERIFY): - // Simply forward data from PLOC Updater to supervisor - std::memcpy(commandBuffer, commandData, commandDataLen); - rawPacket = commandBuffer; - rawPacketLen = commandDataLen; - nextReplyId = PLOC_SPV::ACK_REPORT; - result = RETURN_OK; - break; - default: - sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" - << std::endl; - result = DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; - break; - } - - if (result == RETURN_OK) { - /** - * Flushing the receive buffer to make sure there are no data left from a faulty reply. - */ - uartComIf->flushUartRxBuffer(comCookie); - } - - return result; -} - -void PlocSupervisorHandler::fillCommandAndReplyMap() { - this->insertInCommandMap(PLOC_SPV::GET_HK_REPORT); - this->insertInCommandMap(PLOC_SPV::RESTART_MPSOC); - this->insertInCommandMap(PLOC_SPV::START_MPSOC); - this->insertInCommandMap(PLOC_SPV::SHUTDOWN_MPSOC); - this->insertInCommandMap(PLOC_SPV::SEL_MPSOC_BOOT_IMAGE); - this->insertInCommandMap(PLOC_SPV::SET_BOOT_TIMEOUT); - this->insertInCommandMap(PLOC_SPV::SET_MAX_RESTART_TRIES); - this->insertInCommandMap(PLOC_SPV::RESET_MPSOC); - this->insertInCommandMap(PLOC_SPV::SET_TIME_REF); - this->insertInCommandMap(PLOC_SPV::DISABLE_PERIOIC_HK_TRANSMISSION); - this->insertInCommandMap(PLOC_SPV::GET_BOOT_STATUS_REPORT); - this->insertInCommandMap(PLOC_SPV::UPDATE_AVAILABLE); - this->insertInCommandMap(PLOC_SPV::UPDATE_VERIFY); - this->insertInCommandMap(PLOC_SPV::UPDATE_IMAGE_DATA); - this->insertInCommandMap(PLOC_SPV::WATCHDOGS_ENABLE); - this->insertInCommandMap(PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT); - this->insertInCommandMap(PLOC_SPV::ENABLE_LATCHUP_ALERT); - this->insertInCommandMap(PLOC_SPV::DISABLE_LATCHUP_ALERT); - this->insertInCommandMap(PLOC_SPV::AUTO_CALIBRATE_ALERT); - this->insertInCommandMap(PLOC_SPV::SET_ALERT_LIMIT); - this->insertInCommandMap(PLOC_SPV::SET_ALERT_IRQ_FILTER); - this->insertInCommandMap(PLOC_SPV::SET_ADC_SWEEP_PERIOD); - this->insertInCommandMap(PLOC_SPV::SET_ADC_ENABLED_CHANNELS); - this->insertInCommandMap(PLOC_SPV::SET_ADC_WINDOW_AND_STRIDE); - this->insertInCommandMap(PLOC_SPV::SET_ADC_THRESHOLD); - this->insertInCommandMap(PLOC_SPV::GET_LATCHUP_STATUS_REPORT); - this->insertInCommandMap(PLOC_SPV::COPY_ADC_DATA_TO_MRAM); - this->insertInCommandMap(PLOC_SPV::ENABLE_NVMS); - this->insertInCommandMap(PLOC_SPV::SELECT_NVM); - this->insertInCommandMap(PLOC_SPV::RUN_AUTO_EM_TESTS); - this->insertInCommandMap(PLOC_SPV::WIPE_MRAM); - this->insertInCommandMap(PLOC_SPV::PRINT_CPU_STATS); - this->insertInCommandMap(PLOC_SPV::SET_DBG_VERBOSITY); - this->insertInCommandMap(PLOC_SPV::SET_GPIO); - this->insertInCommandMap(PLOC_SPV::READ_GPIO); - this->insertInCommandMap(PLOC_SPV::RESTART_SUPERVISOR); - this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_ALL); - this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR); - this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR); - this->insertInCommandMap(PLOC_SPV::CAN_LOOPBACK_TEST); - this->insertInCommandAndReplyMap(PLOC_SPV::FIRST_MRAM_DUMP, 3); - this->insertInCommandAndReplyMap(PLOC_SPV::CONSECUTIVE_MRAM_DUMP, 3); - this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); - this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); - this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); - this->insertInReplyMap(PLOC_SPV::BOOT_STATUS_REPORT, 3, &bootStatusReport, - PLOC_SPV::SIZE_BOOT_STATUS_REPORT); - this->insertInReplyMap(PLOC_SPV::LATCHUP_REPORT, 3, &latchupStatusReport, - PLOC_SPV::SIZE_LATCHUP_STATUS_REPORT); -} - -ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t *start, - size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { - - if (nextReplyId == PLOC_SPV::FIRST_MRAM_DUMP) { - *foundId = PLOC_SPV::FIRST_MRAM_DUMP; - return parseMramPackets(start, remainingSize, foundLen); - } - else if (nextReplyId == PLOC_SPV::CONSECUTIVE_MRAM_DUMP) { - *foundId = PLOC_SPV::CONSECUTIVE_MRAM_DUMP; - return parseMramPackets(start, remainingSize, foundLen); - } - - ReturnValue_t result = RETURN_OK; - - uint16_t apid = (*(start) << 8 | *(start + 1)) & APID_MASK; - - switch(apid) { - case(PLOC_SPV::APID_ACK_SUCCESS): - *foundLen = PLOC_SPV::SIZE_ACK_REPORT; - *foundId = PLOC_SPV::ACK_REPORT; - break; - case(PLOC_SPV::APID_ACK_FAILURE): - *foundLen = PLOC_SPV::SIZE_ACK_REPORT; - *foundId = PLOC_SPV::ACK_REPORT; - break; - case(PLOC_SPV::APID_HK_REPORT): - *foundLen = PLOC_SPV::SIZE_HK_REPORT; - *foundId = PLOC_SPV::HK_REPORT; - break; - case(PLOC_SPV::APID_BOOT_STATUS_REPORT): - *foundLen = PLOC_SPV::SIZE_BOOT_STATUS_REPORT; - *foundId = PLOC_SPV::BOOT_STATUS_REPORT; - break; - case(PLOC_SPV::APID_LATCHUP_STATUS_REPORT): - *foundLen = PLOC_SPV::SIZE_LATCHUP_STATUS_REPORT; - *foundId = PLOC_SPV::LATCHUP_REPORT; - break; - case(PLOC_SPV::APID_EXE_SUCCESS): - *foundLen = PLOC_SPV::SIZE_EXE_REPORT; - *foundId = PLOC_SPV::EXE_REPORT; - break; - case(PLOC_SPV::APID_EXE_FAILURE): - *foundLen = PLOC_SPV::SIZE_EXE_REPORT; - *foundId = PLOC_SPV::EXE_REPORT; - break; - default: { - sif::debug << "PlocSupervisorHandler::scanForReply: Reply has invalid apid" << std::endl; - *foundLen = remainingSize; - return INVALID_APID; - } - } - - return result; -} - -ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) { - - ReturnValue_t result = RETURN_OK; - - switch (id) { - case PLOC_SPV::ACK_REPORT: { - result = handleAckReport(packet); - break; - } - case (PLOC_SPV::HK_REPORT): { - result = handleHkReport(packet); - break; - } - case (PLOC_SPV::BOOT_STATUS_REPORT): { - result = handleBootStatusReport(packet); - break; - } - case (PLOC_SPV::LATCHUP_REPORT): { - result = handleLatchupStatusReport(packet); - break; - } - case (PLOC_SPV::FIRST_MRAM_DUMP): - case (PLOC_SPV::CONSECUTIVE_MRAM_DUMP): - result = handleMramDumpPacket(id); - break; - case (PLOC_SPV::EXE_REPORT): { - result = handleExecutionReport(packet); - break; - } - default: { - sif::debug << "PlocSupervisorHandler::interpretDeviceReply: Unknown device reply id" << std::endl; - return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; - } - } - - return result; -} - -void PlocSupervisorHandler::setNormalDatapoolEntriesInvalid(){ - -} - -uint32_t PlocSupervisorHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){ - return 500; -} - -ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) { - - localDataPoolMap.emplace(PLOC_SPV::NUM_TMS, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::TEMP_PS, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::TEMP_PL, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::SOC_STATE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::NVM0_1_STATE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::NVM3_STATE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::MISSION_IO_STATE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::FMC_STATE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::NUM_TCS, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::UPTIME, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::CPULOAD, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::AVAILABLEHEAP, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(PLOC_SPV::BOOT_SIGNAL, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::RESET_COUNTER, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::BOOT_AFTER_MS, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::BOOT_TIMEOUT_MS, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::ACTIVE_NVM, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::BP0_STATE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::BP1_STATE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::BP2_STATE, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(PLOC_SPV::LATCHUP_ID, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::CNT0, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::CNT1, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::CNT2, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::CNT3, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::CNT4, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::CNT5, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::CNT6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_SEC, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_MIN, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_HOUR, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_DAY, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_MON, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_YEAR, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_MSEC, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_IS_SET, new PoolEntry( { 0 })); - - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::iterator command, - uint8_t expectedReplies, bool useAlternateId, - DeviceCommandId_t alternateReplyID) { - - ReturnValue_t result = RETURN_OK; - - uint8_t enabledReplies = 0; - - switch (command->first) { - case PLOC_SPV::GET_HK_REPORT: { - enabledReplies = 3; - result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, - PLOC_SPV::HK_REPORT); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " - << PLOC_SPV::HK_REPORT << " not in replyMap" << std::endl; - } - break; - } - case PLOC_SPV::GET_BOOT_STATUS_REPORT: { - enabledReplies = 3; - result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, - PLOC_SPV::BOOT_STATUS_REPORT); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " - << PLOC_SPV::BOOT_STATUS_REPORT << " not in replyMap" << std::endl; - } - break; - } - case PLOC_SPV::GET_LATCHUP_STATUS_REPORT: { - enabledReplies = 3; - result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, - PLOC_SPV::LATCHUP_REPORT); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " - << PLOC_SPV::LATCHUP_REPORT << " not in replyMap" << std::endl; - } - break; - } - case PLOC_SPV::FIRST_MRAM_DUMP: { - enabledReplies = 2; // expected replies will be increased in handleMramDumpPacket - result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, - PLOC_SPV::FIRST_MRAM_DUMP); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " - << PLOC_SPV::FIRST_MRAM_DUMP << " not in replyMap" << std::endl; - } - break; - } - case PLOC_SPV::CONSECUTIVE_MRAM_DUMP: { - enabledReplies = 2; // expected replies will be increased in handleMramDumpPacket - result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, - PLOC_SPV::CONSECUTIVE_MRAM_DUMP); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " - << PLOC_SPV::CONSECUTIVE_MRAM_DUMP << " not in replyMap" << std::endl; - } - break; - } - case PLOC_SPV::RESTART_MPSOC: - case PLOC_SPV::START_MPSOC: - case PLOC_SPV::SHUTDOWN_MPSOC: - case PLOC_SPV::SEL_MPSOC_BOOT_IMAGE: - case PLOC_SPV::SET_BOOT_TIMEOUT: - case PLOC_SPV::SET_MAX_RESTART_TRIES: - case PLOC_SPV::RESET_MPSOC: - case PLOC_SPV::SET_TIME_REF: - case PLOC_SPV::UPDATE_AVAILABLE: - case PLOC_SPV::UPDATE_IMAGE_DATA: - case PLOC_SPV::UPDATE_VERIFY: - case PLOC_SPV::WATCHDOGS_ENABLE: - case PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT: - case PLOC_SPV::ENABLE_LATCHUP_ALERT: - case PLOC_SPV::DISABLE_LATCHUP_ALERT: - case PLOC_SPV::AUTO_CALIBRATE_ALERT: - case PLOC_SPV::SET_ALERT_LIMIT: - case PLOC_SPV::SET_ALERT_IRQ_FILTER: - case PLOC_SPV::SET_ADC_SWEEP_PERIOD: - case PLOC_SPV::SET_ADC_ENABLED_CHANNELS: - case PLOC_SPV::SET_ADC_WINDOW_AND_STRIDE: - case PLOC_SPV::SET_ADC_THRESHOLD: - case PLOC_SPV::COPY_ADC_DATA_TO_MRAM: - case PLOC_SPV::ENABLE_NVMS: - case PLOC_SPV::SELECT_NVM: - case PLOC_SPV::RUN_AUTO_EM_TESTS: - case PLOC_SPV::WIPE_MRAM: - case PLOC_SPV::SET_DBG_VERBOSITY: - case PLOC_SPV::CAN_LOOPBACK_TEST: - case PLOC_SPV::PRINT_CPU_STATS: - case PLOC_SPV::SET_GPIO: - case PLOC_SPV::READ_GPIO: - case PLOC_SPV::RESTART_SUPERVISOR: - case PLOC_SPV::FACTORY_RESET_CLEAR_ALL: - case PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR: - case PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR: - case PLOC_SPV::REQUEST_LOGGING_DATA: - case PLOC_SPV::DISABLE_PERIOIC_HK_TRANSMISSION: - enabledReplies = 2; - break; - default: - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Unknown command id" << std::endl; - break; - } - - /** - * Every command causes at least one acknowledgment and one execution report. Therefore both - * replies will be enabled here. - */ - result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, - PLOC_SPV::ACK_REPORT); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " - << PLOC_SPV::ACK_REPORT << " not in replyMap" << std::endl; - } - - result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, - PLOC_SPV::EXE_REPORT); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " - << PLOC_SPV::EXE_REPORT << " not in replyMap" << std::endl; - } - - return RETURN_OK; -} - -ReturnValue_t PlocSupervisorHandler::verifyPacket(const uint8_t* start, size_t foundLen) { - - uint16_t receivedCrc = *(start + foundLen - 2) << 8 | *(start + foundLen - 1); - - uint16_t recalculatedCrc = CRC::crc16ccitt(start, foundLen - 2); - - if (receivedCrc != recalculatedCrc) { - return CRC_FAILURE; - } - - return RETURN_OK; -} - -ReturnValue_t PlocSupervisorHandler::handleAckReport(const uint8_t* data) { - - ReturnValue_t result = RETURN_OK; - - result = verifyPacket(data, PLOC_SPV::SIZE_ACK_REPORT); - if(result == CRC_FAILURE) { - sif::error << "PlocSupervisorHandler::handleAckReport: CRC failure" << std::endl; - nextReplyId = PLOC_SPV::NONE; - replyRawReplyIfnotWiretapped(data, PLOC_SPV::SIZE_ACK_REPORT); - triggerEvent(SUPV_CRC_FAILURE_EVENT); - sendFailureReport(PLOC_SPV::ACK_REPORT, CRC_FAILURE); - disableAllReplies(); - return RETURN_OK; - } - - uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK; - - switch(apid) { - case PLOC_SPV::APID_ACK_FAILURE: { - //TODO: Interpretation of status field in acknowledgment report - sif::debug << "PlocSupervisorHandler::handleAckReport: Received Ack failure report" << std::endl; - DeviceCommandId_t commandId = getPendingCommand(); - if (commandId != DeviceHandlerIF::NO_COMMAND_ID) { - triggerEvent(SUPV_ACK_FAILURE, commandId); - } - sendFailureReport(PLOC_SPV::ACK_REPORT, RECEIVED_ACK_FAILURE); - disableAllReplies(); - nextReplyId = PLOC_SPV::NONE; - result = IGNORE_REPLY_DATA; - break; - } - case PLOC_SPV::APID_ACK_SUCCESS: { - setNextReplyId(); - break; - } - default: { - sif::debug << "PlocSupervisorHandler::handleAckReport: Invalid APID in Ack report" << std::endl; - result = RETURN_FAILED; - break; - } - } - - return result; -} - -ReturnValue_t PlocSupervisorHandler::handleExecutionReport(const uint8_t* data) { - - ReturnValue_t result = RETURN_OK; - - result = verifyPacket(data, PLOC_SPV::SIZE_EXE_REPORT); - if(result == CRC_FAILURE) { - sif::error << "PlocSupervisorHandler::handleExecutionReport: CRC failure" << std::endl; - nextReplyId = PLOC_SPV::NONE; - return result; - } - - uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK; - - switch (apid) { - case (PLOC_SPV::APID_EXE_SUCCESS): { - break; - } - case (PLOC_SPV::APID_EXE_FAILURE): { - //TODO: Interpretation of status field in execution report - sif::error << "PlocSupervisorHandler::handleExecutionReport: Received execution failure report" - << std::endl; - DeviceCommandId_t commandId = getPendingCommand(); - if (commandId != DeviceHandlerIF::NO_COMMAND_ID) { - triggerEvent(SUPV_EXE_FAILURE, commandId); - } - else { - sif::debug << "PlocSupervisorHandler::handleExecutionReport: Unknown command id" << std::endl; - } - sendFailureReport(PLOC_SPV::EXE_REPORT, RECEIVED_EXE_FAILURE); - disableExeReportReply(); - result = IGNORE_REPLY_DATA; - break; - } - default: { - sif::error << "PlocSupervisorHandler::handleExecutionReport: Unknown APID" << std::endl; - result = RETURN_FAILED; - break; - } - } - - nextReplyId = PLOC_SPV::NONE; - - return result; -} - -ReturnValue_t PlocSupervisorHandler::handleHkReport(const uint8_t* data) { - - ReturnValue_t result = RETURN_OK; - - result = verifyPacket(data, PLOC_SPV::SIZE_HK_REPORT); - - if(result == CRC_FAILURE) { - sif::error << "PlocSupervisorHandler::handleHkReport: Hk report has invalid crc" - << std::endl; - } - - uint16_t offset = PLOC_SPV::DATA_FIELD_OFFSET; - hkset.tempPs = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 - | *(data + offset + 3); - offset += 4; - hkset.tempPl = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 - | *(data + offset + 3); - offset += 4; - hkset.tempSup = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 - | *(data + offset + 3); - offset += 4; - hkset.uptime = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 - | *(data + offset + 3); - offset += 4; - hkset.cpuLoad = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 - | *(data + offset + 3); - offset += 4; - hkset.availableHeap = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 - | *(data + offset + 3); - offset += 4; - hkset.numTcs = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 - | *(data + offset + 3); - offset += 4; - hkset.numTms = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 - | *(data + offset + 3); - offset += 4; - hkset.socState = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 - | *(data + offset + 3); - offset += 4; - hkset.nvm0_1_state = *(data + offset); - offset += 1; - hkset.nvm3_state = *(data + offset); - offset += 1; - hkset.missionIoState = *(data + offset); - offset += 1; - hkset.fmcState = *(data + offset); - offset += 1; - - nextReplyId = PLOC_SPV::EXE_REPORT; - -#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1 - sif::info << "PlocSupervisorHandler::handleHkReport: temp_ps: " << hkset.tempPs << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: temp_pl: " << hkset.tempPl << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: temp_sup: " << hkset.tempSup << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: uptime: " << hkset.uptime << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: cpu_load: " << hkset.cpuLoad << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: available_heap: " << hkset.availableHeap << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: num_tcs: " << hkset.numTcs << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: num_tms: " << hkset.numTms << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: soc_state: " << hkset.socState << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: nvm0_1_state: " - << static_cast(hkset.nvm0_1_state.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: nvm3_state: " - << static_cast(hkset.nvm3_state.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: missoin_io_state: " - << static_cast(hkset.missionIoState.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleHkReport: fmc_state: " - << static_cast(hkset.fmcState.value) << std::endl; - -#endif - - return result; -} - -ReturnValue_t PlocSupervisorHandler::handleBootStatusReport(const uint8_t* data) { - - ReturnValue_t result = RETURN_OK; - - result = verifyPacket(data, PLOC_SPV::SIZE_BOOT_STATUS_REPORT); - - if(result == CRC_FAILURE) { - sif::error << "PlocSupervisorHandler::handleBootStatusReport: Boot status report has invalid" - " crc" << std::endl; - return result; - } - - uint16_t offset = PLOC_SPV::DATA_FIELD_OFFSET; - bootStatusReport.bootSignal = *(data + offset); - offset += 1; - bootStatusReport.resetCounter = *(data + offset); - offset += 1; - bootStatusReport.bootAfterMs = *(data + offset) << 24 | *(data + offset + 1) << 16 | - *(data + offset + 2) << 8 | *(data + offset + 3); - offset += 4; - bootStatusReport.bootTimeoutMs = *(data + offset) << 24 | *(data + offset + 1) << 16 | - *(data + offset + 2) << 8 | *(data + offset + 3); - offset += 4; - bootStatusReport.activeNvm = *(data + offset); - offset += 1; - bootStatusReport.bp0State = *(data + offset); - offset += 1; - bootStatusReport.bp1State = *(data + offset); - offset += 1; - bootStatusReport.bp2State = *(data + offset); - - nextReplyId = PLOC_SPV::EXE_REPORT; - -#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1 - sif::info << "PlocSupervisorHandler::handleBootStatusReport: Boot signal: " - << static_cast(bootStatusReport.bootSignal.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: Reset counter: " - << static_cast(bootStatusReport.resetCounter.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: BootAfterMs: " - << bootStatusReport.bootAfterMs << " ms" << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: BootTimeoutMs: " - << bootStatusReport.bootTimeoutMs << " ms" << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: Active NVM: " - << static_cast(bootStatusReport.activeNvm.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP0: " - << static_cast(bootStatusReport.bp0State.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP1: " - << static_cast(bootStatusReport.bp1State.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP2: " - << static_cast(bootStatusReport.bp2State.value) << std::endl; -#endif - - return result; -} - -ReturnValue_t PlocSupervisorHandler::handleLatchupStatusReport(const uint8_t* data) { - - ReturnValue_t result = RETURN_OK; - - result = verifyPacket(data, PLOC_SPV::SIZE_LATCHUP_STATUS_REPORT); - - if(result == CRC_FAILURE) { - sif::error << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup status report has " - << "invalid crc" << std::endl; - return result; - } - - uint16_t offset = PLOC_SPV::DATA_FIELD_OFFSET; - latchupStatusReport.id = *(data + offset); - offset += 1; - latchupStatusReport.cnt0 = *(data + offset) << 8 | *(data + offset + 1); - offset += 2; - latchupStatusReport.cnt1 = *(data + offset) << 8 | *(data + offset + 1); - offset += 2; - latchupStatusReport.cnt2 = *(data + offset) << 8 | *(data + offset + 1); - offset += 2; - latchupStatusReport.cnt3 = *(data + offset) << 8 | *(data + offset + 1); - offset += 2; - latchupStatusReport.cnt4 = *(data + offset) << 8 | *(data + offset + 1); - offset += 2; - latchupStatusReport.cnt5 = *(data + offset) << 8 | *(data + offset + 1); - offset += 2; - latchupStatusReport.cnt6 = *(data + offset) << 8 | *(data + offset + 1); - offset += 2; - latchupStatusReport.timeSec = *(data + offset) << 24 | *(data + offset + 1) << 16 | - *(data + offset + 2) << 8 | *(data + offset + 3); - offset += 4; - latchupStatusReport.timeMin = *(data + offset) << 24 | *(data + offset + 1) << 16 | - *(data + offset + 2) << 8 | *(data + offset + 3); - offset += 4; - latchupStatusReport.timeHour = *(data + offset) << 24 | *(data + offset + 1) << 16 | - *(data + offset + 2) << 8 | *(data + offset + 3); - offset += 4; - latchupStatusReport.timeDay = *(data + offset) << 24 | *(data + offset + 1) << 16 | - *(data + offset + 2) << 8 | *(data + offset + 3); - offset += 4; - latchupStatusReport.timeMon = *(data + offset) << 24 | *(data + offset + 1) << 16 | - *(data + offset + 2) << 8 | *(data + offset + 3); - offset += 4; - latchupStatusReport.timeYear = *(data + offset) << 24 | *(data + offset + 1) << 16 | - *(data + offset + 2) << 8 | *(data + offset + 3); - offset += 4; - latchupStatusReport.timeMsec = *(data + offset) << 24 | *(data + offset + 1) << 16 | - *(data + offset + 2) << 8 | *(data + offset + 3); - offset += 4; - latchupStatusReport.isSet = *(data + offset) << 24 | *(data + offset + 1) << 16 | - *(data + offset + 2) << 8 | *(data + offset + 3); - offset += 4; - - nextReplyId = PLOC_SPV::EXE_REPORT; - -#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1 - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup ID: " - << static_cast(latchupStatusReport.id.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT0: " - << latchupStatusReport.cnt0 << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT1: " - << latchupStatusReport.cnt1 << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT2: " - << latchupStatusReport.cnt2 << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT3: " - << latchupStatusReport.cnt3 << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT4: " - << latchupStatusReport.cnt4 << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT5: " - << latchupStatusReport.cnt5 << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT6: " - << latchupStatusReport.cnt6 << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Sec: " - << latchupStatusReport.timeSec << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Min: " - << latchupStatusReport.timeMin << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Hour: " - << latchupStatusReport.timeHour << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Day: " - << latchupStatusReport.timeDay << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Mon: " - << latchupStatusReport.timeMon << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Year: " - << latchupStatusReport.timeYear << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Msec: " - << latchupStatusReport.timeMsec << std::endl; - sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: isSet: 0x" - << std::hex << latchupStatusReport.timeMsec << std::dec << std::endl; -#endif - - return result; -} - -void PlocSupervisorHandler::setNextReplyId() { - switch(getPendingCommand()) { - case PLOC_SPV::GET_HK_REPORT: - nextReplyId = PLOC_SPV::HK_REPORT; - break; - case PLOC_SPV::GET_BOOT_STATUS_REPORT: - nextReplyId = PLOC_SPV::BOOT_STATUS_REPORT; - break; - case PLOC_SPV::GET_LATCHUP_STATUS_REPORT: - nextReplyId = PLOC_SPV::LATCHUP_REPORT; - break; - case PLOC_SPV::FIRST_MRAM_DUMP: - nextReplyId = PLOC_SPV::FIRST_MRAM_DUMP; - break; - case PLOC_SPV::CONSECUTIVE_MRAM_DUMP: - nextReplyId = PLOC_SPV::CONSECUTIVE_MRAM_DUMP; - break; - default: - /* If no telemetry is expected the next reply is always the execution report */ - nextReplyId = PLOC_SPV::EXE_REPORT; - break; - } -} - -size_t PlocSupervisorHandler::getNextReplyLength(DeviceCommandId_t commandId){ - - size_t replyLen = 0; - - if (nextReplyId == PLOC_SPV::NONE) { - return replyLen; - } - - if (nextReplyId == PLOC_SPV::FIRST_MRAM_DUMP - || nextReplyId == PLOC_SPV::CONSECUTIVE_MRAM_DUMP) { - /** - * Try to read 20 MRAM packets. If reply is larger, the packets will be read with the - * next doSendRead call. The command will be as long active as the packet with the sequence - * count indicating the last packet has not been received. - */ - replyLen = PLOC_SPV::MAX_PACKET_SIZE * 20; - return replyLen; - } - - DeviceReplyIter iter = deviceReplyMap.find(nextReplyId); - if (iter != deviceReplyMap.end()) { - if (iter->second.delayCycles == 0) { - /* Reply inactive */ - return replyLen; - } - replyLen = iter->second.replyLen; - } - else { - sif::debug << "PlocSupervisorHandler::getNextReplyLength: No entry for reply with reply id " - << std::hex << nextReplyId << " in deviceReplyMap" << std::endl; - } - - return replyLen; -} - -void PlocSupervisorHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId) { - - ReturnValue_t result = RETURN_OK; - - if (wiretappingMode == RAW) { - /* Data already sent in doGetRead() */ - return; - } - - DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId); - if (iter == deviceReplyMap.end()) { - sif::debug << "PlocSupervisorHandler::handleDeviceTM: Unknown reply id" << std::endl; - return; - } - MessageQueueId_t queueId = iter->second.command->second.sendReplyTo; - - if (queueId == NO_COMMANDER) { - return; - } - - result = actionHelper.reportData(queueId, replyId, data, dataSize); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::handleDeviceTM: Failed to report data" << std::endl; - } -} - -void PlocSupervisorHandler::prepareEmptyCmd(uint16_t apid) { - PLOC_SPV::EmptyPacket packet(apid); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::prepareSelBootImageCmd(const uint8_t * commandData) { - PLOC_SPV::MPSoCBootSelect packet(*commandData, *(commandData + 1), *(commandData + 2), - *(commandData + 3)); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -ReturnValue_t PlocSupervisorHandler::prepareSetTimeRefCmd() { - Clock::TimeOfDay_t time; - ReturnValue_t result = Clock::getDateAndTime(&time); - if (result != RETURN_OK) { - sif::warning << "PlocSupervisorHandler::prepareSetTimeRefCmd: Failed to get current time" - << std::endl; - return GET_TIME_FAILURE; - } - PLOC_SPV::SetTimeRef packet(&time); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - return RETURN_OK; -} - -void PlocSupervisorHandler::prepareDisableHk() { - PLOC_SPV::DisablePeriodicHkTransmission packet; - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::prepareSetBootTimeoutCmd(const uint8_t * commandData) { - uint32_t timeout = *(commandData) << 24 | *(commandData + 1) << 16 | *(commandData + 2) << 8 - | *(commandData + 3); - PLOC_SPV::SetBootTimeout packet(timeout); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::prepareRestartTriesCmd(const uint8_t * commandData) { - uint8_t restartTries = *(commandData); - PLOC_SPV::SetRestartTries packet(restartTries); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::prepareWatchdogsEnableCmd(const uint8_t * commandData) { - uint8_t offset = 0; - uint8_t watchdogPs = *(commandData + offset); - offset += 1; - uint8_t watchdogPl = *(commandData + offset); - offset += 1; - uint8_t watchdogInt = *(commandData + offset); - PLOC_SPV::WatchdogsEnable packet(watchdogPs, watchdogPl, watchdogInt); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -ReturnValue_t PlocSupervisorHandler::prepareWatchdogsConfigTimeoutCmd(const uint8_t * commandData) { - uint8_t offset = 0; - uint8_t watchdog = *(commandData + offset); - offset += 1; - if (watchdog > 2) { - return INVALID_WATCHDOG; - } - uint32_t timeout = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 - | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); - if (timeout < 1000 || timeout > 360000) { - return INVALID_WATCHDOG_TIMEOUT; - } - PLOC_SPV::WatchdogsConfigTimeout packet(watchdog, timeout); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - return RETURN_OK; -} - -ReturnValue_t PlocSupervisorHandler::prepareLatchupConfigCmd(const uint8_t* commandData, - DeviceCommandId_t deviceCommand) { - ReturnValue_t result = RETURN_OK; - uint8_t latchupId = *commandData; - if (latchupId > 6) { - return INVALID_LATCHUP_ID; - } - switch (deviceCommand) { - case (PLOC_SPV::ENABLE_LATCHUP_ALERT): { - PLOC_SPV::LatchupAlert packet(true, latchupId); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - break; - } - case (PLOC_SPV::DISABLE_LATCHUP_ALERT): { - PLOC_SPV::LatchupAlert packet(false, latchupId); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - break; - } - default: { - sif::debug << "PlocSupervisorHandler::prepareLatchupConfigCmd: Invalid command id" - << std::endl; - result = RETURN_FAILED; - break; - } - } - return result; -} - -ReturnValue_t PlocSupervisorHandler::prepareAutoCalibrateAlertCmd(const uint8_t* commandData) { - uint8_t offset = 0; - uint8_t latchupId = *commandData; - offset += 1; - uint32_t mg = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 - | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); - if (latchupId > 6) { - return INVALID_LATCHUP_ID; - } - PLOC_SPV::AutoCalibrateAlert packet(latchupId, mg); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - return RETURN_OK; -} - -ReturnValue_t PlocSupervisorHandler::prepareSetAlertIrqFilterCmd(const uint8_t* commandData) { - uint8_t latchupId = *commandData; - uint8_t tp = *(commandData + 1); - uint8_t div = *(commandData + 2); - if (latchupId > 6) { - return INVALID_LATCHUP_ID; - } - PLOC_SPV::SetAlertIrqFilter packet(latchupId, tp, div); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - return RETURN_OK; -} - -ReturnValue_t PlocSupervisorHandler::prepareSetAlertLimitCmd(const uint8_t* commandData) { - uint8_t offset = 0; - uint8_t latchupId = *commandData; - offset += 1; - uint32_t dutycycle = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 - | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); - if (latchupId > 6) { - return INVALID_LATCHUP_ID; - } - PLOC_SPV::SetAlertlimit packet(latchupId, dutycycle); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - return RETURN_OK; -} - -ReturnValue_t PlocSupervisorHandler::prepareSetAdcSweetPeriodCmd(const uint8_t* commandData) { - uint32_t sweepPeriod = *(commandData) << 24 | *(commandData + 1) << 16 - | *(commandData + 2) << 8 | *(commandData + 3); - if (sweepPeriod < 21) { - return SWEEP_PERIOD_TOO_SMALL; - } - PLOC_SPV::SetAdcSweepPeriod packet(sweepPeriod); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - return RETURN_OK; -} - -void PlocSupervisorHandler::prepareSetAdcEnabledChannelsCmd(const uint8_t* commandData) { - uint16_t ch = *(commandData) << 8 | *(commandData + 1); - PLOC_SPV::SetAdcEnabledChannels packet(ch); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::prepareSetAdcWindowAndStrideCmd(const uint8_t* commandData) { - uint8_t offset = 0; - uint16_t windowSize = *(commandData + offset) << 8 | *(commandData + offset + 1); - offset += 2; - uint16_t stridingStepSize = *(commandData + offset) << 8 | *(commandData + offset + 1); - PLOC_SPV::SetAdcWindowAndStride packet(windowSize, stridingStepSize); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::prepareSetAdcThresholdCmd(const uint8_t* commandData) { - uint32_t threshold = *(commandData) << 24 | *(commandData + 1) << 16 | *(commandData + 2) << 8 - | *(commandData + 3); - PLOC_SPV::SetAdcThreshold packet(threshold); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::prepareEnableNvmsCmd(const uint8_t* commandData) { - uint8_t n01 = *commandData; - uint8_t n3 = *(commandData + 1); - PLOC_SPV::EnableNvms packet(n01, n3); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::prepareSelectNvmCmd(const uint8_t* commandData) { - uint8_t mem = *commandData; - PLOC_SPV::SelectNvm packet(mem); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -ReturnValue_t PlocSupervisorHandler::prepareRunAutoEmTest(const uint8_t* commandData) { - uint8_t test = *commandData; - if (test != 1 && test != 2) { - return INVALID_TEST_PARAM; - } - PLOC_SPV::RunAutoEmTests packet(test); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - return RETURN_OK; -} - -ReturnValue_t PlocSupervisorHandler::prepareWipeMramCmd(const uint8_t* commandData) { - uint32_t start = 0; - uint32_t stop = 0; - size_t size = sizeof(start) + sizeof(stop); - SerializeAdapter::deSerialize(&start, &commandData, &size, SerializeIF::Endianness::BIG); - SerializeAdapter::deSerialize(&stop, &commandData, &size, SerializeIF::Endianness::BIG); - if ((stop - start) <= 0) { - return INVALID_MRAM_ADDRESSES; - } - PLOC_SPV::MramCmd packet(start, stop, PLOC_SPV::MramCmd::MramAction::WIPE); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - return RETURN_OK; -} - -ReturnValue_t PlocSupervisorHandler::prepareDumpMramCmd(const uint8_t* commandData) { - uint32_t start = 0; - uint32_t stop = 0; - size_t size = sizeof(start) + sizeof(stop); - SerializeAdapter::deSerialize(&start, &commandData, &size, SerializeIF::Endianness::BIG); - SerializeAdapter::deSerialize(&stop, &commandData, &size, SerializeIF::Endianness::BIG); - PLOC_SPV::MramCmd packet(start, stop, PLOC_SPV::MramCmd::MramAction::DUMP); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); - if ((stop - start) <= 0) { - return INVALID_MRAM_ADDRESSES; - } - expectedMramDumpPackets = (stop - start) / PLOC_SPV::MAX_DATA_CAPACITY; - if ((stop - start) % PLOC_SPV::MAX_DATA_CAPACITY) { - expectedMramDumpPackets++; - } - receivedMramDumpPackets = 0; - return RETURN_OK; -} - -void PlocSupervisorHandler::preparePrintCpuStatsCmd(const uint8_t* commandData) { - uint8_t en = *commandData; - PLOC_SPV::PrintCpuStats packet(en); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::prepareSetDbgVerbosityCmd(const uint8_t* commandData) { - uint8_t vb = *commandData; - PLOC_SPV::SetDbgVerbosity packet(vb); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandData) { - uint8_t port = *commandData; - uint8_t pin = *(commandData + 1); - uint8_t val = *(commandData + 2); - PLOC_SPV::SetGpio packet(port, pin, val); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::prepareReadGpioCmd(const uint8_t* commandData) { - uint8_t port = *commandData; - uint8_t pin = *(commandData + 1); - PLOC_SPV::ReadGpio packet(port, pin); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - -void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { - memcpy(commandBuffer, packetData, fullSize); - rawPacket = commandBuffer; - rawPacketLen = fullSize; - nextReplyId = PLOC_SPV::ACK_REPORT; -} - -void PlocSupervisorHandler::disableAllReplies() { - - DeviceReplyMap::iterator iter; - - /* Disable ack reply */ - iter = deviceReplyMap.find(PLOC_SPV::ACK_REPORT); - DeviceReplyInfo *info = &(iter->second); - info->delayCycles = 0; - info->command = deviceCommandMap.end(); - - DeviceCommandId_t commandId = getPendingCommand(); - - /* If the command expects a telemetry packet the appropriate tm reply will be disabled here */ - switch (commandId) { - case PLOC_SPV::GET_HK_REPORT: { - iter = deviceReplyMap.find(PLOC_SPV::GET_HK_REPORT); - info = &(iter->second); - info->delayCycles = 0; - info->command = deviceCommandMap.end(); - break; - } - default: { - break; - } - } - - /* We must always disable the execution report reply here */ - disableExeReportReply(); -} - -void PlocSupervisorHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status) { - - DeviceReplyIter iter = deviceReplyMap.find(replyId); - - if (iter == deviceReplyMap.end()) { - sif::debug << "PlocSupervisorHandler::sendFailureReport: Reply not in reply map" << std::endl; - return; - } - - DeviceCommandInfo* info = &(iter->second.command->second); - - if (info == nullptr) { - sif::debug << "PlocSupervisorHandler::sendFailureReport: Reply has no active command" << std::endl; - return; - } - - if (info->sendReplyTo != NO_COMMANDER) { - actionHelper.finish(false, info->sendReplyTo, iter->first, status); - } - info->isExecuting = false; -} - -void PlocSupervisorHandler::disableExeReportReply() { - DeviceReplyIter iter = deviceReplyMap.find(PLOC_SPV::EXE_REPORT); - DeviceReplyInfo *info = &(iter->second); - info->delayCycles = 0; - info->command = deviceCommandMap.end(); - /* Expected replies is set to one here. The value will set to 0 in replyToReply() */ - info->command->second.expectedReplies = 1; -} - -ReturnValue_t PlocSupervisorHandler::parseMramPackets(const uint8_t *packet, size_t remainingSize, - size_t* foundLen) { - ReturnValue_t result = IGNORE_FULL_PACKET; - uint16_t packetLen = 0; - *foundLen = 0; - - for (size_t idx = 0; idx < remainingSize; idx++) { - std::memcpy(spacePacketBuffer + bufferTop, packet + idx, 1); - bufferTop += 1; - *foundLen += 1; - if (bufferTop >= PLOC_SPV::SPACE_PACKET_HEADER_LENGTH) { - packetLen = readSpacePacketLength(spacePacketBuffer); - } - - if (bufferTop == PLOC_SPV::SPACE_PACKET_HEADER_LENGTH + packetLen + 1) { - packetInBuffer = true; - bufferTop = 0; - return checkMramPacketApid(); - } - - if (bufferTop == PLOC_SPV::MAX_PACKET_SIZE) { - *foundLen = remainingSize; - disableAllReplies(); - bufferTop = 0; - return MRAM_PACKET_PARSING_FAILURE; - } - } - - return result; -} - -ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket(DeviceCommandId_t id) { - - ReturnValue_t result = RETURN_FAILED; - - // Prepare packet for downlink - if (packetInBuffer) { - uint16_t packetLen = readSpacePacketLength(spacePacketBuffer); - result = verifyPacket(spacePacketBuffer, PLOC_SPV::SPACE_PACKET_HEADER_LENGTH + packetLen + 1); - if (result != RETURN_OK) { - sif::warning << "PlocSupervisorHandler::handleMramDumpPacket: CRC failure" << std::endl; - return result; - } - handleMramDumpFile(id); - if (downlinkMramDump == true) { - handleDeviceTM(spacePacketBuffer + PLOC_SPV::SPACE_PACKET_HEADER_LENGTH, packetLen - 1, - id); - } - packetInBuffer = false; - receivedMramDumpPackets++; - if (expectedMramDumpPackets == receivedMramDumpPackets) { - nextReplyId = PLOC_SPV::EXE_REPORT; - } - increaseExpectedMramReplies(id); - return RETURN_OK; - } - return result; -} - -void PlocSupervisorHandler::increaseExpectedMramReplies(DeviceCommandId_t id) { - DeviceReplyMap::iterator mramDumpIter = deviceReplyMap.find(id); - DeviceReplyMap::iterator exeReportIter = deviceReplyMap.find(PLOC_SPV::EXE_REPORT); - if (mramDumpIter == deviceReplyMap.end()) { - sif::debug << "PlocSupervisorHandler::increaseExpectedMramReplies: Dump MRAM reply not " - << "in reply map" << std::endl; - return; - } - if (exeReportIter == deviceReplyMap.end()) { - sif::debug << "PlocSupervisorHandler::increaseExpectedMramReplies: Execution report not " - << "in reply map" << std::endl; - return; - } - DeviceReplyInfo *mramReplyInfo = &(mramDumpIter->second); - if (mramReplyInfo == nullptr) { - sif::debug << "PlocSupervisorHandler::increaseExpectedReplies: MRAM reply info nullptr" - << std::endl; - return; - } - DeviceReplyInfo *exeReplyInfo = &(exeReportIter->second); - if (exeReplyInfo == nullptr) { - sif::debug << "PlocSupervisorHandler::increaseExpectedReplies: Execution reply info" - << " nullptr" << std::endl; - return; - } - DeviceCommandInfo* info = &(mramReplyInfo->command->second); - if (info == nullptr){ - sif::debug << "PlocSupervisorHandler::increaseExpectedReplies: Command info nullptr" - << std::endl; - return; - } - uint8_t sequenceFlags = spacePacketBuffer[2] >> 6; - if (sequenceFlags != static_cast(PLOC_SPV::SequenceFlags::LAST_PKT) - && (sequenceFlags != static_cast(PLOC_SPV::SequenceFlags::STANDALONE_PKT))) { - // Command expects at least one MRAM packet more and the execution report - info->expectedReplies = 2; - // Wait maximum of 2 cycles for next MRAM packet - mramReplyInfo->delayCycles = 2; - // Also adapting delay cycles for execution report - exeReplyInfo->delayCycles = 3; - } - else { - // Command expects the execution report - info->expectedReplies = 1; - mramReplyInfo->delayCycles = 0; - } - return; -} - -ReturnValue_t PlocSupervisorHandler::checkMramPacketApid() { - uint16_t apid = (spacePacketBuffer[0] << 8 | spacePacketBuffer[1]) & PLOC_SPV::APID_MASK; - if (apid != PLOC_SPV::APID_MRAM_DUMP_TM) { - return NO_MRAM_PACKET; - } - return APERIODIC_REPLY; -} - -ReturnValue_t PlocSupervisorHandler::handleMramDumpFile(DeviceCommandId_t id) { - ReturnValue_t result = RETURN_OK; - uint16_t packetLen = readSpacePacketLength(spacePacketBuffer); - uint8_t sequenceFlags = readSequenceFlags(spacePacketBuffer); - if (id == PLOC_SPV::FIRST_MRAM_DUMP) { - if (sequenceFlags == static_cast(PLOC_SPV::SequenceFlags::FIRST_PKT) - || (sequenceFlags == static_cast(PLOC_SPV::SequenceFlags::STANDALONE_PKT))) { - result = createMramDumpFile(); - if (result != RETURN_OK) { - return result; - } - } - } - if (not std::filesystem::exists(activeMramFile)) { - sif::warning << "PlocSupervisorHandler::handleMramDumpFile: MRAM file does not exist" - << std::endl; - return MRAM_FILE_NOT_EXISTS; - } - std::ofstream file(activeMramFile, std::ios_base::app | std::ios_base::out); - file.write( - reinterpret_cast(spacePacketBuffer + PLOC_SPV::SPACE_PACKET_HEADER_LENGTH), - packetLen - 1); - file.close(); - return RETURN_OK; -} - -uint16_t PlocSupervisorHandler::readSpacePacketLength(uint8_t* spacePacket) { - return spacePacket[4] << 8 | spacePacket[5]; -} - -uint8_t PlocSupervisorHandler::readSequenceFlags(uint8_t* spacePacket) { - return spacePacketBuffer[2] >> 6; -} - -ReturnValue_t PlocSupervisorHandler::createMramDumpFile() { - ReturnValue_t result = RETURN_OK; - std::string timeStamp; - result = getTimeStampString(timeStamp); - if (result != RETURN_OK) { - return result; - } - - std::string filename = "mram-dump--" + timeStamp + ".bin"; - -#if BOARD_TE0720 == 0 - std::string currentMountPrefix = sdcMan->getCurrentMountPrefix(); -#else - std::string currentMountPrefix("/mnt/sd0"); -#endif /* BOARD_TE0720 == 0 */ - - // Check if path to PLOC directory exists - if (not std::filesystem::exists(std::string(currentMountPrefix + "/" + plocFilePath))) { - sif::warning << "PlocSupervisorHandler::createMramDumpFile: Ploc path does not exist" - << std::endl; - return PATH_DOES_NOT_EXIST; - } - activeMramFile = currentMountPrefix + "/" + plocFilePath + "/" + filename; - // Create new file - std::ofstream file(activeMramFile, std::ios_base::out); - file.close(); - - return RETURN_OK; -} - -ReturnValue_t PlocSupervisorHandler::getTimeStampString(std::string& timeStamp) { - Clock::TimeOfDay_t time; - ReturnValue_t result = Clock::getDateAndTime(&time); - if (result != RETURN_OK) { - sif::warning << "PlocSupervisorHandler::createMramDumpFile: Failed to get current time" - << std::endl; - return GET_TIME_FAILURE; - } - timeStamp = std::to_string(time.year) + "-" + std::to_string(time.month) + "-" - + std::to_string(time.day) + "--" + std::to_string(time.hour) + "-" - + std::to_string(time.minute) + "-" + std::to_string(time.second); - return RETURN_OK; -} diff --git a/bsp_q7s/devices/PlocSupervisorHandler.h b/bsp_q7s/devices/PlocSupervisorHandler.h deleted file mode 100644 index f22c86b1..00000000 --- a/bsp_q7s/devices/PlocSupervisorHandler.h +++ /dev/null @@ -1,342 +0,0 @@ -#ifndef MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ -#define MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ - -#include "devicedefinitions/PlocSupervisorDefinitions.h" -#include - -#include -#include - -/** - * @brief This is the device handler for the supervisor of the PLOC which is programmed by - * Thales. - * - * @details The PLOC uses the space packet protocol for communication. To each command the PLOC - * answers with at least one acknowledgment and one execution report. - * Flight manual: - * https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/PLOC_Commands - * ILH ICD: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/ - * Arbeitsdaten/08_Used%20Components/PLOC&fileid=940960 - * @author J. Meier - */ -class PlocSupervisorHandler: public DeviceHandlerBase { -public: - - PlocSupervisorHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF * comCookie); - virtual ~PlocSupervisorHandler(); - - virtual ReturnValue_t initialize() override; - -protected: - void doStartUp() override; - void doShutDown() override; - ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override; - ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) override; - void fillCommandAndReplyMap() override; - ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, - const uint8_t * commandData,size_t commandDataLen) override; - ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize, - DeviceCommandId_t *foundId, size_t *foundLen) override; - ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) override; - void setNormalDatapoolEntriesInvalid() override; - uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; - ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) override; - ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator command, - uint8_t expectedReplies = 1, bool useAlternateId = false, - DeviceCommandId_t alternateReplyID = 0) override; - size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override; - -private: - - static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_SUPERVISOR_HANDLER; - - //! [EXPORT] : [COMMENT] Space Packet received from PLOC supervisor has invalid CRC - static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0); - //! [EXPORT] : [COMMENT] Received ACK failure reply from PLOC supervisor - static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1); - //! [EXPORT] : [COMMENT] Received execution failure reply from PLOC supervisor - static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2); - //! [EXPORT] : [COMMENT] Received space packet with invalid APID from PLOC supervisor - static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3); - //! [EXPORT] : [COMMENT] Failed to read current system time - static const ReturnValue_t GET_TIME_FAILURE = MAKE_RETURN_CODE(0xA4); - //! [EXPORT] : [COMMENT] Invalid communication interface specified - static const ReturnValue_t INVALID_UART_COM_IF = MAKE_RETURN_CODE(0xA5); - //! [EXPORT] : [COMMENT] Received command with invalid watchdog parameter. Valid watchdogs are 0 for PS, 1 for PL and 2 for INT - static const ReturnValue_t INVALID_WATCHDOG = MAKE_RETURN_CODE(0xA6); - //! [EXPORT] : [COMMENT] Received watchdog timeout config command with invalid timeout. Valid timeouts must be in the range between 1000 and 360000 ms. - static const ReturnValue_t INVALID_WATCHDOG_TIMEOUT = MAKE_RETURN_CODE(0xA7); - //! [EXPORT] : [COMMENT] Received latchup config command with invalid latchup ID - static const ReturnValue_t INVALID_LATCHUP_ID = MAKE_RETURN_CODE(0xA8); - //! [EXPORT] : [COMMENT] Received set adc sweep period command with invalid sweep period. Must be larger than 21. - static const ReturnValue_t SWEEP_PERIOD_TOO_SMALL = MAKE_RETURN_CODE(0xA9); - //! [EXPORT] : [COMMENT] Receive auto EM test command with invalid test param. Valid params are 1 and 2. - static const ReturnValue_t INVALID_TEST_PARAM = MAKE_RETURN_CODE(0xAA); - //! [EXPORT] : [COMMENT] Returned when scanning for MRAM dump packets failed. - static const ReturnValue_t MRAM_PACKET_PARSING_FAILURE = MAKE_RETURN_CODE(0xAB); - //! [EXPORT] : [COMMENT] Returned when the start and stop addresses of the MRAM dump or MRAM wipe commands are invalid (e.g. start address bigger than stop address) - static const ReturnValue_t INVALID_MRAM_ADDRESSES = MAKE_RETURN_CODE(0xAC); - //! [EXPORT] : [COMMENT] Expect reception of an MRAM dump packet but received space packet with other apid. - static const ReturnValue_t NO_MRAM_PACKET = MAKE_RETURN_CODE(0xAD); - //! [EXPORT] : [COMMENT] Path to PLOC directory on SD card does not exist - static const ReturnValue_t PATH_DOES_NOT_EXIST = MAKE_RETURN_CODE(0xAE); - //! [EXPORT] : [COMMENT] MRAM dump file does not exists. The file should actually already have been created with the reception of the first dump packet. - static const ReturnValue_t MRAM_FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xAF); - - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; - - //! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet - static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW); - //! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report - static const Event SUPV_ACK_FAILURE = MAKE_EVENT(2, severity::LOW); - //! [EXPORT] : [COMMENT] PLOC received execution failure report - static const Event SUPV_EXE_FAILURE = MAKE_EVENT(3, severity::LOW); - //! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc - static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(4, severity::LOW); - - static const uint16_t APID_MASK = 0x7FF; - static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF; - - uint8_t commandBuffer[PLOC_SPV::MAX_COMMAND_SIZE]; - - /** - * This variable is used to store the id of the next reply to receive. This is necessary - * because the PLOC sends as reply to each command at least one acknowledgment and execution - * report. - */ - DeviceCommandId_t nextReplyId = PLOC_SPV::NONE; - - UartComIF* uartComIf = nullptr; - - PLOC_SPV::HkSet hkset; - PLOC_SPV::BootStatusReport bootStatusReport; - PLOC_SPV::LatchupStatusReport latchupStatusReport; - - /** Number of expected replies following the MRAM dump command */ - uint32_t expectedMramDumpPackets = 0; - uint32_t receivedMramDumpPackets = 0; - /** Set to true as soon as a complete space packet is present in the spacePacketBuffer */ - bool packetInBuffer = false; - /** Points to the next free position in the space packet buffer */ - uint16_t bufferTop = 0; - - /** This buffer is used to concatenate space packets received in two different read steps */ - uint8_t spacePacketBuffer[PLOC_SPV::MAX_PACKET_SIZE]; - -#if BOARD_TE0720 == 0 - SdCardManager* sdcMan = nullptr; -#endif /* BOARD_TE0720 == 0 */ - - /** Path to PLOC specific files on SD card */ - std::string plocFilePath = "ploc"; - std::string activeMramFile; - - /** Setting this variable to true will enable direct downlink of MRAM packets */ - bool downlinkMramDump = false; - - /** - * @brief This function checks the crc of the received PLOC reply. - * - * @param start Pointer to the first byte of the reply. - * @param foundLen Pointer to the length of the whole packet. - * - * @return RETURN_OK if CRC is ok, otherwise CRC_FAILURE. - */ - ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen); - - /** - * @brief This function handles the acknowledgment report. - * - * @param data Pointer to the data holding the acknowledgment report. - * - * @return RETURN_OK if successful, otherwise an error code. - */ - ReturnValue_t handleAckReport(const uint8_t* data); - - /** - * @brief This function handles the data of a execution report. - * - * @param data Pointer to the received data packet. - * - * @return RETURN_OK if successful, otherwise an error code. - */ - ReturnValue_t handleExecutionReport(const uint8_t* data); - - /** - * @brief This function handles the housekeeping report. This means verifying the CRC of the - * reply and filling the appropriate dataset. - * - * @param data Pointer to the data buffer holding the housekeeping read report. - * - * @return RETURN_OK if successful, otherwise an error code. - */ - ReturnValue_t handleHkReport(const uint8_t* data); - - /** - * @brief This function calls the function to check the CRC of the received boot status report - * and fills the associated dataset with the boot status information. - */ - ReturnValue_t handleBootStatusReport(const uint8_t* data); - - ReturnValue_t handleLatchupStatusReport(const uint8_t* data); - - /** - * @brief Depending on the current active command, this function sets the reply id of the - * next reply after a successful acknowledgment report has been received. This is - * required by the function getNextReplyLength() to identify the length of the next - * reply to read. - */ - void setNextReplyId(); - - /** - * @brief This function handles action message replies in case the telemetry has been - * requested by another object. - * - * @param data Pointer to the telemetry data. - * @param dataSize Size of telemetry in bytes. - * @param replyId Id of the reply. This will be added to the ActionMessage. - */ - void handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId); - - /** - * @brief This function prepares a space packet which does not transport any data in the - * packet data field apart from the crc. - */ - void prepareEmptyCmd(uint16_t apid); - - /** - * @brief This function initializes the space packet to select the boot image of the MPSoC. - */ - void prepareSelBootImageCmd(const uint8_t * commandData); - - void prepareDisableHk(); - - /** - * @brief This function fills the commandBuffer with the data to update the time of the - * PLOC supervisor. - */ - ReturnValue_t prepareSetTimeRefCmd(); - - /** - * @brief This function fills the commandBuffer with the data to change the boot timeout - * value in the PLOC supervisor. - */ - void prepareSetBootTimeoutCmd(const uint8_t * commandData); - - void prepareRestartTriesCmd(const uint8_t * commandData); - - /** - * @brief This function fills the command buffer with the packet to enable or disable the - * watchdogs on the PLOC. - */ - void prepareWatchdogsEnableCmd(const uint8_t * commandData); - - /** - * @brief This function fills the command buffer with the packet to set the watchdog timer - * of one of the three watchdogs (PS, PL, INT). - */ - ReturnValue_t prepareWatchdogsConfigTimeoutCmd(const uint8_t * commandData); - - ReturnValue_t prepareLatchupConfigCmd(const uint8_t* commandData, - DeviceCommandId_t deviceCommand); - ReturnValue_t prepareAutoCalibrateAlertCmd(const uint8_t* commandData); - ReturnValue_t prepareSetAlertLimitCmd(const uint8_t* commandData); - ReturnValue_t prepareSetAlertIrqFilterCmd(const uint8_t* commandData); - ReturnValue_t prepareSetAdcSweetPeriodCmd(const uint8_t* commandData); - void prepareSetAdcEnabledChannelsCmd(const uint8_t* commandData); - void prepareSetAdcWindowAndStrideCmd(const uint8_t* commandData); - void prepareSetAdcThresholdCmd(const uint8_t* commandData); - void prepareEnableNvmsCmd(const uint8_t* commandData); - void prepareSelectNvmCmd(const uint8_t* commandData); - ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData); - ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData); - ReturnValue_t prepareDumpMramCmd(const uint8_t* commandData); - void preparePrintCpuStatsCmd(const uint8_t* commandData); - void prepareSetDbgVerbosityCmd(const uint8_t* commandData); - void prepareSetGpioCmd(const uint8_t* commandData); - void prepareReadGpioCmd(const uint8_t* commandData); - - - /** - * @brief Copies the content of a space packet to the command buffer. - */ - void packetToOutBuffer(uint8_t* packetData, size_t fullSize); - - /** - * @brief In case an acknowledgment failure reply has been received this function disables - * all previously enabled commands and resets the exepected replies variable of an - * active command. - */ - void disableAllReplies(); - - /** - * @brief This function sends a failure report if the active action was commanded by an other - * object. - * - * @param replyId The id of the reply which signals a failure. - * @param status A status byte which gives information about the failure type. - */ - void sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status); - - /** - * @brief This function disables the execution report reply. Within this function also the - * the variable expectedReplies of an active command will be set to 0. - */ - void disableExeReportReply(); - - /** - * @brief Function is called in scanForReply and fills the spacePacketBuffer with the read - * data until a full packet has been received. - */ - ReturnValue_t parseMramPackets(const uint8_t *packet, size_t remainingSize, size_t* foundlen); - - /** - * @brief This function generates the Service 8 packets for the MRAM dump data. - */ - ReturnValue_t handleMramDumpPacket(DeviceCommandId_t id); - - /** - * @brief With this function the number of expected replies following an MRAM dump command - * will be increased. This is necessary to release the command in case not all replies - * have been received. - */ - void increaseExpectedMramReplies(DeviceCommandId_t id); - - /** - * @brief Function checks if the packet written to the space packet buffer is really a - * MRAM dump packet. - */ - ReturnValue_t checkMramPacketApid(); - - /** - * @brief Writes the data of the MRAM dump to a file. The file will be created when receiving - * the first packet. - */ - ReturnValue_t handleMramDumpFile(DeviceCommandId_t id); - - /** - * @brief Extracts the length field of a spacePacket referenced by the spacePacket pointer. - * - * @param spacePacket Pointer to the buffer holding the space packet. - * - * @return The value stored in the length field of the data field. - */ - uint16_t readSpacePacketLength(uint8_t* spacePacket); - - /** - * @brief Extracts the sequence flags from a space packet referenced by the spacePacket - * pointer. - * - * @param spacePacket Pointer to the buffer holding the space packet. - * - * @return uint8_t where the two least significant bits hold the sequence flags. - */ - uint8_t readSequenceFlags(uint8_t* spacePacket); - - ReturnValue_t createMramDumpFile(); - ReturnValue_t getTimeStampString(std::string& timeStamp); -}; - -#endif /* MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ */ diff --git a/bsp_q7s/devices/PlocUpdater.cpp b/bsp_q7s/devices/PlocUpdater.cpp deleted file mode 100644 index 592a2c0d..00000000 --- a/bsp_q7s/devices/PlocUpdater.cpp +++ /dev/null @@ -1,405 +0,0 @@ -#include "fsfw/ipc/QueueFactory.h" -#include "PlocUpdater.h" - -#include -#include -#include - -PlocUpdater::PlocUpdater(object_id_t objectId) : - SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) { - commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); -} - -PlocUpdater::~PlocUpdater() { -} - -ReturnValue_t PlocUpdater::initialize() { -#if BOARD_TE0720 == 0 - sdcMan = SdCardManager::instance(); -#endif - ReturnValue_t result = SystemObject::initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = commandActionHelper.initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = actionHelper.initialize(commandQueue); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t PlocUpdater::performOperation(uint8_t operationCode) { - readCommandQueue(); - doStateMachine(); - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { - ReturnValue_t result = RETURN_FAILED; - - if (state != State::IDLE) { - return IS_BUSY; - } - - if (size > MAX_PLOC_UPDATE_PATH) { - return NAME_TOO_LONG; - } - - switch (actionId) { - case UPDATE_A_UBOOT: - image = Image::A; - partition = Partition::UBOOT; - break; - case UPDATE_A_BITSTREAM: - image = Image::A; - partition = Partition::BITSTREAM; - break; - case UPDATE_A_LINUX: - image = Image::A; - partition = Partition::LINUX_OS; - break; - case UPDATE_A_APP_SW: - image = Image::A; - partition = Partition::APP_SW; - break; - case UPDATE_B_UBOOT: - image = Image::B; - partition = Partition::UBOOT; - break; - case UPDATE_B_BITSTREAM: - image = Image::B; - partition = Partition::BITSTREAM; - break; - case UPDATE_B_LINUX: - image = Image::B; - partition = Partition::LINUX_OS; - break; - case UPDATE_B_APP_SW: - image = Image::B; - partition = Partition::APP_SW; - break; - default: - return INVALID_ACTION_ID; - } - - result = getImageLocation(data, size); - - if (result != RETURN_OK) { - return result; - } - - state = State::UPDATE_AVAILABLE; - - return EXECUTION_FINISHED; -} - -MessageQueueId_t PlocUpdater::getCommandQueue() const { - return commandQueue->getId(); -} - -MessageQueueIF* PlocUpdater::getCommandQueuePtr() { - return commandQueue; -} - -void PlocUpdater::readCommandQueue() { - CommandMessage message; - ReturnValue_t result; - - for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK; - result = commandQueue->receiveMessage(&message)) { - if (result != RETURN_OK) { - continue; - } - result = actionHelper.handleActionMessage(&message); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; - } - - result = commandActionHelper.handleReply(&message); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; - } - - sif::debug << "PlocUpdater::readCommandQueue: Received message with invalid format" - << std::endl; - } -} - -void PlocUpdater::doStateMachine() { - switch (state) { - case State::IDLE: - break; - case State::UPDATE_AVAILABLE: - commandUpdateAvailable(); - break; - case State::UPDATE_TRANSFER: - commandUpdatePacket(); - break; - case State::UPDATE_VERIFY: - commandUpdateVerify(); - break; - case State::COMMAND_EXECUTING: - break; - default: - sif::debug << "PlocUpdater::doStateMachine: Invalid state" << std::endl; - break; - } -} - -ReturnValue_t PlocUpdater::checkNameLength(size_t size) { - if (size > MAX_PLOC_UPDATE_PATH) { - return NAME_TOO_LONG; - } - return RETURN_OK; -} - -ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { - ReturnValue_t result = checkNameLength(size); - if (result != RETURN_OK) { - return result; - } - -#if BOARD_TE0720 == 0 - // Check if file is stored on SD card and if associated SD card is mounted - if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { - if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { - sif::warning << "PlocUpdater::getImageLocation: SD card 0 not mounted" << std::endl; - return SD_NOT_MOUNTED; - } - } - else if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { - if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { - sif::warning << "PlocUpdater::getImageLocation: SD card 1 not mounted" << std::endl; - return SD_NOT_MOUNTED; - } - } - else { - //update image not stored on SD card - } -#endif /* BOARD_TE0720 == 0 */ - - updateFile = std::string(reinterpret_cast(data), size); - - // Check if file exists - if(not std::filesystem::exists(updateFile)) { - return FILE_NOT_EXISTS; - } - return RETURN_OK; -} - -void PlocUpdater::stepSuccessfulReceived(ActionId_t actionId, - uint8_t step) { -} - -void PlocUpdater::stepFailedReceived(ActionId_t actionId, uint8_t step, - ReturnValue_t returnCode) { -} - -void PlocUpdater::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) { - -} - -void PlocUpdater::completionSuccessfulReceived(ActionId_t actionId) { - switch (pendingCommand) { - case (PLOC_SPV::UPDATE_AVAILABLE): - state = State::UPDATE_TRANSFER; - break; - case (PLOC_SPV::UPDATE_IMAGE_DATA): - if (remainingPackets == 0) { - packetsSent = 0; // Reset packets sent variable for next update sequence - state = State::UPDATE_VERIFY; - } - else { - state = State::UPDATE_TRANSFER; - } - break; - case (PLOC_SPV::UPDATE_VERIFY): - triggerEvent(UPDATE_FINISHED); - state = State::IDLE; - pendingCommand = PLOC_SPV::NONE; - break; - default: - sif::debug << "PlocUpdater::completionSuccessfulReceived: Invalid pending command" - << std::endl; - state = State::IDLE; - break; - } -} - -void PlocUpdater::completionFailedReceived(ActionId_t actionId, - ReturnValue_t returnCode) { - switch(pendingCommand) { - case(PLOC_SPV::UPDATE_AVAILABLE): { - triggerEvent(UPDATE_AVAILABLE_FAILED); - break; - } - case(PLOC_SPV::UPDATE_IMAGE_DATA): { - triggerEvent(UPDATE_TRANSFER_FAILED, packetsSent); - break; - } - case(PLOC_SPV::UPDATE_VERIFY): { - triggerEvent(UPDATE_VERIFY_FAILED); - break; - } - default: - sif::debug << "PlocUpdater::completionFailedReceived: Invalid pending command " - << std::endl; - break; - } - state = State::IDLE; -} - -void PlocUpdater::commandUpdateAvailable() { - ReturnValue_t result = RETURN_OK; - - if (not std::filesystem::exists(updateFile)) { - triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast(state)); - state = State::IDLE; - return; - } - - std::ifstream file(updateFile, std::ifstream::binary); - file.seekg(0, file.end); - imageSize = static_cast(file.tellg()); - file.close(); - - numOfUpdatePackets = imageSize / MAX_SP_DATA ; - if (imageSize % MAX_SP_DATA) { - numOfUpdatePackets++; - } - - remainingPackets = numOfUpdatePackets; - packetsSent = 0; - - calcImageCrc(); - - PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_AVAILABLE, static_cast(image), - static_cast(partition), imageSize, imageCrc, numOfUpdatePackets); - - result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, - PLOC_SPV::UPDATE_AVAILABLE, packet.getWholeData(), packet.getFullSize()); - if (result != RETURN_OK) { - sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available" - << " packet to supervisor handler" << std::endl; - triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_AVAILABLE); - state = State::IDLE; - pendingCommand = PLOC_SPV::NONE; - return; - } - - pendingCommand = PLOC_SPV::UPDATE_AVAILABLE; - state = State::COMMAND_EXECUTING; - return; -} - -void PlocUpdater::commandUpdatePacket() { - ReturnValue_t result = RETURN_OK; - uint16_t payloadLength = 0; - - if (not std::filesystem::exists(updateFile)) { - triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast(state), packetsSent); - state = State::IDLE; - return; - } - - std::ifstream file(updateFile, std::ifstream::binary); - file.seekg(packetsSent * MAX_SP_DATA, file.beg); - - if (remainingPackets == 1) { - payloadLength = imageSize - static_cast(file.tellg()); - } - else { - payloadLength = MAX_SP_DATA; - } - - PLOC_SPV::UpdatePacket packet(payloadLength); - file.read(reinterpret_cast(packet.getDataFieldPointer()), payloadLength); - file.close(); - // sequence count of first packet is 1 - packet.setPacketSequenceCount((packetsSent + 1) & PLOC_SPV::SEQUENCE_COUNT_MASK); - if (numOfUpdatePackets > 1) { - adjustSequenceFlags(packet); - } - packet.makeCrc(); - - result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, - PLOC_SPV::UPDATE_IMAGE_DATA, packet.getWholeData(), packet.getFullSize()); - - if (result != RETURN_OK) { - sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update" - << " packet to supervisor handler" << std::endl; - triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_IMAGE_DATA); - state = State::IDLE; - pendingCommand = PLOC_SPV::NONE; - return; - } - - remainingPackets--; - packetsSent++; - - pendingCommand = PLOC_SPV::UPDATE_IMAGE_DATA; - state = State::COMMAND_EXECUTING; -} - -void PlocUpdater::commandUpdateVerify() { - ReturnValue_t result = RETURN_OK; - - PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_VERIFY, static_cast(image), - static_cast(partition), imageSize, imageCrc, numOfUpdatePackets); - - result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, - PLOC_SPV::UPDATE_VERIFY, packet.getWholeData(), packet.getFullSize()); - if (result != RETURN_OK) { - sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available" - << " packet to supervisor handler" << std::endl; - triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_VERIFY); - state = State::IDLE; - pendingCommand = PLOC_SPV::NONE; - return; - } - state = State::COMMAND_EXECUTING; - pendingCommand = PLOC_SPV::UPDATE_VERIFY; - return; -} - -void PlocUpdater::calcImageCrc() { - std::ifstream file(updateFile, std::ifstream::binary); - file.seekg(0, file.end); - uint32_t count; - uint32_t bit; - uint32_t remainder = INITIAL_REMAINDER_32; - char input; - for (count = 0; count < imageSize; count++) { - file.seekg(count, file.beg); - file.read(&input, 1); - remainder ^= (input << 16); - for (bit = 8; bit > 0; --bit) { - if (remainder & TOPBIT_32) { - remainder = (remainder << 1) ^ POLYNOMIAL_32; - } else { - remainder = (remainder << 1); - } - } - } - file.close(); - imageCrc = (remainder ^ FINAL_XOR_VALUE_32); -} - -void PlocUpdater::adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet) { - if (packetsSent == 0) { - packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::FIRST_PKT)); - } - else if (remainingPackets == 1) { - packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::LAST_PKT)); - } - else { - packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::CONTINUED_PKT)); - } -} - diff --git a/bsp_q7s/devices/PlocUpdater.h b/bsp_q7s/devices/PlocUpdater.h deleted file mode 100644 index d016b9e5..00000000 --- a/bsp_q7s/devices/PlocUpdater.h +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef MISSION_DEVICES_PLOCUPDATER_H_ -#define MISSION_DEVICES_PLOCUPDATER_H_ - -#include "OBSWConfig.h" -#include "devicedefinitions/PlocSupervisorDefinitions.h" - -#include "fsfw/action/CommandActionHelper.h" -#include "fsfw/action/ActionHelper.h" -#include "fsfw/action/HasActionsIF.h" -#include "fsfw/action/CommandsActionsIF.h" -#include "fsfw/returnvalues/HasReturnvaluesIF.h" -#include "fsfw/tasks/ExecutableObjectIF.h" -#include "fsfw/objectmanager/SystemObject.h" -#include "bsp_q7s/memory/SdCardManager.h" -#include "linux/fsfwconfig/objects/systemObjectList.h" -#include "fsfw/tmtcpacket/SpacePacket.h" - - -/** - * @brief An object of this class can be used to perform the software updates of the PLOC. The - * software update will be read from one of the SD cards, split into multiple space - * packets and sent to the PlocSupervisorHandler. - * - * @details The MPSoC has two boot memories (NVM0 and NVM1) where each stores two images (Partition A - * and Partition B) - * - * @author J. Meier - */ -class PlocUpdater : public SystemObject, - public HasActionsIF, - public ExecutableObjectIF, - public HasReturnvaluesIF, - public CommandsActionsIF { -public: - - static const ActionId_t UPDATE_A_UBOOT = 0; - static const ActionId_t UPDATE_A_BITSTREAM = 1; - static const ActionId_t UPDATE_A_LINUX = 2; - static const ActionId_t UPDATE_A_APP_SW = 3; - static const ActionId_t UPDATE_B_UBOOT = 4; - static const ActionId_t UPDATE_B_BITSTREAM = 5; - static const ActionId_t UPDATE_B_LINUX = 6; - static const ActionId_t UPDATE_B_APP_SW = 7; - - PlocUpdater(object_id_t objectId); - virtual ~PlocUpdater(); - - ReturnValue_t performOperation(uint8_t operationCode = 0) override; - ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, - const uint8_t* data, size_t size); - MessageQueueId_t getCommandQueue() const; - ReturnValue_t initialize() override; - MessageQueueIF* getCommandQueuePtr() override; - void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override; - void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override; - void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override; - void completionSuccessfulReceived(ActionId_t actionId) override; - void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override; - -private: - - static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_UPDATER; - - //! [EXPORT] : [COMMENT] Updater is already performing an update - static const ReturnValue_t UPDATER_BUSY = MAKE_RETURN_CODE(0xA0); - //! [EXPORT] : [COMMENT] Received update command with invalid path string (too long). - static const ReturnValue_t NAME_TOO_LONG = MAKE_RETURN_CODE(0xA1); - //! [EXPORT] : [COMMENT] Received command to initiate update but SD card with update image not mounted. - static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA2); - //! [EXPORT] : [COMMENT] Update file received with update command does not exist. - static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA3); - - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_UPDATER; - - //! [EXPORT] : [COMMENT] Try to read update file but the file does not exist. - //! P1: Indicates in which state the file read fails - //! P2: During the update transfer the second parameter gives information about the number of already sent packets - static const Event UPDATE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW); - //! [EXPORT] : [COMMENT] Failed to send command to supervisor handler - //! P1: Return value of CommandActionHelper::commandAction - //! P2: Action ID of command to send - static const Event ACTION_COMMANDING_FAILED = MAKE_EVENT(1, severity::LOW); - //! [EXPORT] : [COMMENT] Supervisor handler replied action message indicating a command execution failure of the update available command - static const Event UPDATE_AVAILABLE_FAILED = MAKE_EVENT(2, severity::LOW); - //! [EXPORT] : [COMMENT] Supervisor handler failed to transfer an update space packet. - //! P1: Parameter holds the number of update packets already sent (inclusive the failed packet) - static const Event UPDATE_TRANSFER_FAILED = MAKE_EVENT(3, severity::LOW); - //! [EXPORT] : [COMMENT] Supervisor failed to execute the update verify command. - static const Event UPDATE_VERIFY_FAILED = MAKE_EVENT(4, severity::LOW); - //! [EXPORT] : [COMMENT] MPSoC update successful completed - static const Event UPDATE_FINISHED = MAKE_EVENT(5, severity::INFO); - - static const uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE; - static const size_t MAX_PLOC_UPDATE_PATH = 50; - static const size_t SD_PREFIX_LENGTH = 8; - // Maximum size of update payload data per space packet (max size of space packet is 1024 bytes) - static const size_t MAX_SP_DATA = 1016; - - static const uint32_t TOPBIT_32 = (1 << 31); - static const uint32_t POLYNOMIAL_32 = 0x04C11DB7; - static const uint32_t INITIAL_REMAINDER_32 = 0xFFFFFFFF; - static const uint32_t FINAL_XOR_VALUE_32 = 0xFFFFFFFF; - - MessageQueueIF* commandQueue = nullptr; - -#if BOARD_TE0720 == 0 - SdCardManager* sdcMan = nullptr; -#endif - CommandActionHelper commandActionHelper; - - ActionHelper actionHelper; - - enum class State: uint8_t { - IDLE, - UPDATE_AVAILABLE, - UPDATE_TRANSFER, - UPDATE_VERIFY, - COMMAND_EXECUTING - }; - - State state = State::IDLE; - - ActionId_t pendingCommand = PLOC_SPV::NONE; - - enum class Image: uint8_t { - NONE, - A, - B - }; - - Image image = Image::NONE; - - enum class Partition: uint8_t { - NONE, - UBOOT, - BITSTREAM, - LINUX_OS, - APP_SW - }; - - Partition partition = Partition::NONE; - - uint32_t packetsSent = 0; - uint32_t remainingPackets = 0; - // Number of packets required to transfer the update image - uint32_t numOfUpdatePackets = 0; - - std::string updateFile; - uint32_t imageSize = 0; - uint32_t imageCrc = 0; - - void readCommandQueue(); - void doStateMachine(); - - /** - * @brief Extracts the path and name of the update image from the service 8 command data. - */ - ReturnValue_t getImageLocation(const uint8_t* data, size_t size); - - ReturnValue_t checkNameLength(size_t size); - - /** - * @brief Prepares and sends update available command to PLOC supervisor handler. - */ - void commandUpdateAvailable(); - - /** - * @brief Prepares and sends and update packet to the PLOC supervisor handler. - */ - void commandUpdatePacket(); - - /** - * @brief Prepares and sends the update verification packet to the PLOC supervisor handler. - */ - void commandUpdateVerify(); - - void calcImageCrc(); - - void adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet); -}; - -#endif /* MISSION_DEVICES_PLOCUPDATER_H_ */ diff --git a/bsp_q7s/devices/devicedefinitions/PlocMemDumpDefinitions.h b/bsp_q7s/devices/devicedefinitions/PlocMemDumpDefinitions.h deleted file mode 100644 index 6e44cf35..00000000 --- a/bsp_q7s/devices/devicedefinitions/PlocMemDumpDefinitions.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_PLOCMEMDUMPDEFINITIONS_H_ -#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_PLOCMEMDUMPDEFINITIONS_H_ - -#include - -class MemoryParams: public SerialLinkedListAdapter { -public: - - /** - * @brief Constructor - * @param startAddress Start of address range to dump - * @param endAddress End of address range to dump - */ - MemoryParams(uint32_t startAddress, uint32_t endAddress) : - startAddress(startAddress), endAddress(endAddress) { - setLinks(); - } -private: - - void setLinks() { - setStart(&startAddress); - startAddress.setNext(&endAddress); - } - - SerializeElement startAddress; - SerializeElement endAddress; - -}; - - - - -#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_PLOCMEMDUMPDEFINITIONS_H_ */ diff --git a/bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h b/bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h deleted file mode 100644 index 0235d281..00000000 --- a/bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ /dev/null @@ -1,1609 +0,0 @@ -#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_ -#define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_ - -#include -#include -#include -#include -#include -#include - -namespace PLOC_SPV { - -/** Command IDs */ -static const DeviceCommandId_t NONE = 0; -static const DeviceCommandId_t GET_HK_REPORT = 1; -static const DeviceCommandId_t RESTART_MPSOC = 2; -static const DeviceCommandId_t START_MPSOC = 3; -static const DeviceCommandId_t SHUTDOWN_MPSOC = 4; -static const DeviceCommandId_t SEL_MPSOC_BOOT_IMAGE = 5; -static const DeviceCommandId_t SET_BOOT_TIMEOUT = 6; -static const DeviceCommandId_t SET_MAX_RESTART_TRIES = 7; -static const DeviceCommandId_t RESET_MPSOC = 8; -static const DeviceCommandId_t SET_TIME_REF = 9; -static const DeviceCommandId_t DISABLE_PERIOIC_HK_TRANSMISSION = 10; -static const DeviceCommandId_t GET_BOOT_STATUS_REPORT = 11; -/** Notifies the supervisor that a new update is available for the MPSoC */ -static const DeviceCommandId_t UPDATE_AVAILABLE = 12; -static const DeviceCommandId_t WATCHDOGS_ENABLE = 13; -static const DeviceCommandId_t WATCHDOGS_CONFIG_TIMEOUT = 14; -static const DeviceCommandId_t ENABLE_LATCHUP_ALERT = 15; -static const DeviceCommandId_t DISABLE_LATCHUP_ALERT = 16; -static const DeviceCommandId_t AUTO_CALIBRATE_ALERT = 17; -static const DeviceCommandId_t SET_ALERT_LIMIT = 18; -static const DeviceCommandId_t SET_ALERT_IRQ_FILTER = 19; -static const DeviceCommandId_t SET_ADC_SWEEP_PERIOD = 20; -static const DeviceCommandId_t SET_ADC_ENABLED_CHANNELS = 21; -static const DeviceCommandId_t SET_ADC_WINDOW_AND_STRIDE = 22; -static const DeviceCommandId_t SET_ADC_THRESHOLD = 23; -static const DeviceCommandId_t GET_LATCHUP_STATUS_REPORT = 24; -static const DeviceCommandId_t COPY_ADC_DATA_TO_MRAM = 25; -static const DeviceCommandId_t ENABLE_NVMS = 26; -static const DeviceCommandId_t SELECT_NVM = 27; -static const DeviceCommandId_t RUN_AUTO_EM_TESTS = 28; -static const DeviceCommandId_t WIPE_MRAM = 29; -static const DeviceCommandId_t FIRST_MRAM_DUMP = 30; -static const DeviceCommandId_t SET_DBG_VERBOSITY = 31; -static const DeviceCommandId_t CAN_LOOPBACK_TEST = 32; -static const DeviceCommandId_t PRINT_CPU_STATS = 33; -static const DeviceCommandId_t SET_GPIO = 34; -static const DeviceCommandId_t READ_GPIO = 35; -static const DeviceCommandId_t RESTART_SUPERVISOR = 36; -static const DeviceCommandId_t FACTORY_RESET_CLEAR_ALL = 37; -static const DeviceCommandId_t REQUEST_LOGGING_DATA = 38; -static const DeviceCommandId_t UPDATE_IMAGE_DATA = 39; -static const DeviceCommandId_t FACTORY_RESET_CLEAR_MIRROR = 40; -static const DeviceCommandId_t FACTORY_RESET_CLEAR_CIRCULAR = 41; -static const DeviceCommandId_t UPDATE_VERIFY = 42; -static const DeviceCommandId_t CONSECUTIVE_MRAM_DUMP = 43; - -/** Reply IDs */ -static const DeviceCommandId_t ACK_REPORT = 50; -static const DeviceCommandId_t EXE_REPORT = 51; -static const DeviceCommandId_t HK_REPORT = 52; -static const DeviceCommandId_t BOOT_STATUS_REPORT = 53; -static const DeviceCommandId_t LATCHUP_REPORT = 54; - -static const uint16_t SIZE_ACK_REPORT = 14; -static const uint16_t SIZE_EXE_REPORT = 14; -static const uint16_t SIZE_HK_REPORT = 48; -static const uint16_t SIZE_BOOT_STATUS_REPORT = 22; -static const uint16_t SIZE_LATCHUP_STATUS_REPORT = 55; - -/** - * SpacePacket apids of telemetry packets - */ -static const uint16_t APID_ACK_SUCCESS = 0x200; -static const uint16_t APID_ACK_FAILURE = 0x201; -static const uint16_t APID_EXE_SUCCESS = 0x202; -static const uint16_t APID_EXE_FAILURE = 0x203; -static const uint16_t APID_HK_REPORT = 0x204; -static const uint16_t APID_BOOT_STATUS_REPORT = 0x205; -static const uint16_t APID_UPDATE_STATUS_REPORT = 0x206; -static const uint16_t APID_WDG_STATUS_REPORT = 0x207; -static const uint16_t APID_LATCHUP_STATUS_REPORT = 0x208; -static const uint16_t APID_SOC_SYSMON = 0x209; -static const uint16_t APID_MRAM_DUMP_TM = 0x20A; -static const uint16_t APID_SRAM = 0x20B; -static const uint16_t APID_NOR_DATA = 0x20C; -static const uint16_t APID_DATA_LOGGER_DATA = 0x20D; - -/** - * APIDs of telecommand packets - */ -static const uint16_t APID_RESTART_MPSOC = 0xA0; -static const uint16_t APID_START_MPSOC = 0xA1; -static const uint16_t APID_SHUTWOWN_MPSOC = 0xA2; -static const uint16_t APID_SEL_MPSOC_BOOT_IMAGE = 0xA3; -static const uint16_t APID_SET_BOOT_TIMEOUT = 0xA4; -static const uint16_t APID_SET_MAX_RESTART_TRIES = 0xA5; -static const uint16_t APID_RESET_MPSOC = 0xA6; -static const uint16_t APID_GET_BOOT_STATUS_RPT = 0xA8; -static const uint16_t APID_UPDATE_AVAILABLE = 0xB0; -static const uint16_t APID_UPDATE_IMAGE_DATA = 0xB1; -static const uint16_t APID_UPDATE_VERIFY = 0xB2; -static const uint16_t APID_WTD_ENABLE = 0xC0; -static const uint16_t APID_WTD_CONFIG_TIMEOUT = 0xC1; -static const uint16_t APID_SET_TIME_REF = 0xC2; -static const uint16_t APID_DISABLE_HK = 0xC3; -static const uint16_t APID_ENABLE_LATCHUP_ALERT = 0xD0; -static const uint16_t APID_DISABLE_LATCHUP_ALERT = 0xD1; -static const uint16_t APID_AUTO_CALIBRATE_ALERT = 0xD2; -static const uint16_t APID_SET_ALERT_LIMIT = 0xD3; -static const uint16_t APID_SET_ALERT_IRQ_FILTER = 0xD4; -static const uint16_t APID_SET_ADC_SWEEP_PERIOD = 0xD5; -static const uint16_t APID_SET_ADC_ENABLED_CHANNELS = 0xD6; -static const uint16_t APID_SET_ADC_WINDOW_AND_STRIDE = 0xD7; -static const uint16_t APID_SET_ADC_THRESHOLD = 0xD8; -static const uint16_t APID_GET_LATCHUP_STATUS_REPORT = 0xD9; -static const uint16_t APID_COPY_ADC_DATA_TO_MRAM = 0xDA; -static const uint16_t APID_ENABLE_NVMS = 0xF0; -static const uint16_t APID_SELECT_NVM = 0xF1; -static const uint16_t APID_RUN_AUTO_EM_TESTS = 0xF2; -static const uint16_t APID_WIPE_MRAM = 0xF3; -static const uint16_t APID_DUMP_MRAM = 0xF4; -static const uint16_t APID_SET_DBG_VERBOSITY = 0xF5; -static const uint16_t APID_CAN_LOOPBACK_TEST = 0xF6; -static const uint16_t APID_PRINT_CPU_STATS = 0xF8; -static const uint16_t APID_SET_GPIO = 0xF9; -static const uint16_t APID_READ_GPIO = 0xFA; -static const uint16_t APID_RESTART_SUPERVISOR = 0xFB; -static const uint16_t APID_FACTORY_RESET = 0xFC; -static const uint16_t APID_REQUEST_LOGGING_DATA = 0xFD; - -static const uint16_t APID_GET_HK_REPORT = 0xC6; - -static const uint16_t APID_MASK = 0x3FF; -static const uint16_t SEQUENCE_COUNT_MASK = 0xFFF; - -/** Offset from first byte in Space packet to first byte of data field */ -static const uint8_t DATA_FIELD_OFFSET = 6; - -/** - * Space packet length for fixed size packets. This is the size of the whole packet data - * field. For the length field in the space packet this size will be substracted by one. - */ -static const uint16_t LENGTH_EMPTY_TC = 2; // Only CRC will be transported with the data field - -/** This is the maximum length of a space packet as defined by the TAS ICD */ -static const size_t MAX_COMMAND_SIZE = 1024; -static const size_t MAX_DATA_CAPACITY = 1016; -/** This is the maximum size of a space packet for the supervisor */ -static const size_t MAX_PACKET_SIZE = 1024; - -static const uint8_t SPACE_PACKET_HEADER_LENGTH = 6; - -enum class SequenceFlags: uint8_t { - CONTINUED_PKT = 0b00, FIRST_PKT = 0b01, LAST_PKT = 0b10, STANDALONE_PKT = 0b11 -}; - -enum PoolIds - : lp_id_t { - NUM_TMS, - TEMP_PS, - TEMP_PL, - SOC_STATE, - NVM0_1_STATE, - NVM3_STATE, - MISSION_IO_STATE, - FMC_STATE, - NUM_TCS, - TEMP_SUP, - UPTIME, - CPULOAD, - AVAILABLEHEAP, - BOOT_SIGNAL, - RESET_COUNTER, - BOOT_AFTER_MS, - BOOT_TIMEOUT_MS, - ACTIVE_NVM, - BP0_STATE, - BP1_STATE, - BP2_STATE, - - LATCHUP_ID, - CNT0, - CNT1, - CNT2, - CNT3, - CNT4, - CNT5, - CNT6, - LATCHUP_RPT_TIME_SEC, - LATCHUP_RPT_TIME_MIN, - LATCHUP_RPT_TIME_HOUR, - LATCHUP_RPT_TIME_DAY, - LATCHUP_RPT_TIME_MON, - LATCHUP_RPT_TIME_YEAR, - LATCHUP_RPT_TIME_MSEC, - LATCHUP_RPT_TIME_USEC, - LATCHUP_RPT_TIME_IS_SET, -}; - -static const uint8_t HK_SET_ENTRIES = 13; -static const uint8_t BOOT_REPORT_SET_ENTRIES = 8; -static const uint8_t LATCHUP_RPT_SET_ENTRIES = 16; - -static const uint32_t HK_SET_ID = HK_REPORT; -static const uint32_t BOOT_REPORT_SET_ID = BOOT_STATUS_REPORT; -static const uint32_t LATCHUP_RPT_ID = LATCHUP_REPORT; - -/** - * @brief With this class a space packet can be created which does not contain any data. - */ -class EmptyPacket: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param apid The APID to set in the space packet. - * - * @note Sequence count of empty packet is always 1. - */ - EmptyPacket(uint16_t apid) : - SpacePacket(LENGTH_EMPTY_TC - 1, true, apid, 1) { - calcCrc(); - } - -private: - - /** - * @brief CRC calculation which involves only the header in an empty packet - */ - void calcCrc() { - - /* Calculate crc */ - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader)); - - /* Add crc to packet data field of space packet */ - size_t serializedSize = 0; - uint8_t* crcPos = this->localData.fields.buffer; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class can be used to generate the space packet selecting the boot image of - * of the MPSoC. - */ -class MPSoCBootSelect: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param mem The memory to boot from: NVM0 (0), NVM1 (1) - * @param bp0 Partition pin 0 - * @param bp1 Partition pin 1 - * @param bp2 Partition pin 2 - */ - MPSoCBootSelect(uint8_t mem, uint8_t bp0, uint8_t bp1, uint8_t bp2) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SEL_MPSOC_BOOT_IMAGE, - DEFAULT_SEQUENCE_COUNT), mem(mem), bp0(bp0), bp1(bp1), bp2(bp2) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 6; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint8_t MEM_OFFSET = 0; - static const uint8_t BP0_OFFSET = 1; - static const uint8_t BP1_OFFSET = 2; - static const uint8_t BP2_OFFSET = 3; - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t mem = 0; - uint8_t bp0 = 0; - uint8_t bp1 = 0; - uint8_t bp2 = 0; - - void initPacket() { - uint8_t* data_field_start = this->localData.fields.buffer; - std::memcpy(data_field_start + MEM_OFFSET, &mem, sizeof(mem)); - std::memcpy(data_field_start + BP0_OFFSET, &bp0, sizeof(bp0)); - std::memcpy(data_field_start + BP1_OFFSET, &bp1, sizeof(bp1)); - std::memcpy(data_field_start + BP2_OFFSET, &bp2, sizeof(bp2)); - /* Calculate crc */ - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - - /* Add crc to packet data field of space packet */ - size_t serializedSize = 0; - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class generates the space packet to update the time of the PLOC supervisor. - */ -class SetTimeRef: public SpacePacket { -public: - - SetTimeRef(Clock::TimeOfDay_t* time) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_TIME_REF, DEFAULT_SEQUENCE_COUNT) { - initPacket(time); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 34; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - void initPacket(Clock::TimeOfDay_t* time) { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&time->second, &data_field_ptr, &serializedSize, - sizeof(time->second), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&time->minute, &data_field_ptr, &serializedSize, - sizeof(time->minute), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&time->hour, &data_field_ptr, &serializedSize, - sizeof(time->hour), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&time->day, &data_field_ptr, &serializedSize, - sizeof(time->day), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&time->month, &data_field_ptr, &serializedSize, - sizeof(time->month), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&time->year, &data_field_ptr, &serializedSize, - sizeof(time->year), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint32_t milliseconds = time->usecond / 1000; - SerializeAdapter::serialize(&milliseconds, &data_field_ptr, &serializedSize, - sizeof(milliseconds), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint32_t isSet = 0xFFFFFFFF; - SerializeAdapter::serialize(&isSet, &data_field_ptr, &serializedSize, - sizeof(isSet), SerializeIF::Endianness::BIG); - serializedSize = 0; - /* Calculate crc */ - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - SerializeAdapter::serialize(&crc, &data_field_ptr, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class can be used to generate the set boot timout command. - */ -class SetBootTimeout: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param timeout The boot timeout in milliseconds. - */ - SetBootTimeout(uint32_t timeout) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_BOOT_TIMEOUT, 1), timeout(timeout) { - initPacket(); - } - -private: - - uint32_t timeout = 0; - - /** boot timeout value (uint32_t) and crc (uint16_t) */ - static const uint16_t DATA_FIELD_LENGTH = 6; - - void initPacket() { - - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&timeout, &data_field_ptr, &serializedSize, - sizeof(timeout), SerializeIF::Endianness::BIG); - /* Calculate crc */ - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - /* Add crc to packet data field of space packet */ - serializedSize = 0; - SerializeAdapter::serialize(&crc, &data_field_ptr, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class can be used to generate the space packet to set the maximum boot tries. - */ -class SetRestartTries: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param restartTries Maximum restart tries to set. - */ - SetRestartTries(uint8_t restartTries) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_MAX_RESTART_TRIES, 1), restartTries( - restartTries) { - initPacket(); - } - -private: - - uint8_t restartTries = 0; - - /** Restart tries value (uint8_t) and crc (uint16_t) */ - static const uint16_t DATA_FIELD_LENGTH = 3; - - void initPacket() { - uint8_t* data_field_ptr = this->localData.fields.buffer; - *data_field_ptr = restartTries; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - size_t serializedSize = 0; - uint8_t* crcPtr = data_field_ptr + 1; - SerializeAdapter::serialize(&crc, &crcPtr, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the command to notify the supervisor that a new update for the - * MPSoC is available. - */ -class UpdateAvailable: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param imageSelect - * @param imagePartition - * @param imageSize - * @param imageCrc - * @param numberOfPackets - */ - UpdateAvailable(uint8_t imageSelect, uint8_t imagePartition, uint32_t imageSize, - uint32_t imageCrc, uint32_t numberOfPackets) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_UPDATE_AVAILABLE, - DEFAULT_SEQUENCE_COUNT), imageSelect(imageSelect), imagePartition( - imagePartition), imageSize(imageSize), imageCrc(imageCrc), numberOfPackets( - numberOfPackets) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 16; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t imageSelect = 0; - uint8_t imagePartition = 0; - uint32_t imageSize = 0; - uint32_t imageCrc = 0; - uint32_t numberOfPackets = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&imageSelect, &data_field_ptr, &serializedSize, - sizeof(imageSelect), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&imagePartition, &data_field_ptr, &serializedSize, - sizeof(imagePartition), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&imageSize, &data_field_ptr, &serializedSize, - sizeof(imageSize), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&imageCrc, &data_field_ptr, &serializedSize, - sizeof(imageCrc), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&numberOfPackets, &data_field_ptr, &serializedSize, - sizeof(numberOfPackets), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief With this class the space packet can be generated to disable to periodic transmission - * of housekeeping data. Normally, this will be disabled by default. However, adding this - * command can be useful for debugging. - */ -class DisablePeriodicHkTransmission: public SpacePacket { -public: - - /** - * @brief Constructor - */ - DisablePeriodicHkTransmission() : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_DISABLE_HK, 1) { - initPacket(); - } - -private: - - uint8_t disableHk = 0; - - /** Restart tries value (uint8_t) and crc (uint16_t) */ - static const uint16_t DATA_FIELD_LENGTH = 3; - - void initPacket() { - uint8_t* data_field_ptr = this->localData.fields.buffer; - *data_field_ptr = disableHk; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - size_t serializedSize = 0; - uint8_t* crcPtr = data_field_ptr + 1; - SerializeAdapter::serialize(&crc, &crcPtr, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the command to enable the watchdogs of the PLOC. - */ -class WatchdogsEnable: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param watchdogPs Enables processing system watchdog - * @param watchdogPl Enables programmable logic wathdog - * @param watchdogInt - */ - WatchdogsEnable(uint8_t watchdogPs, uint8_t watchdogPl, uint8_t watchdogInt) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_WTD_ENABLE, DEFAULT_SEQUENCE_COUNT), - watchdogPs(watchdogPs), watchdogPl(watchdogPl), watchdogInt(watchdogInt) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 5; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t watchdogPs = 0; - uint8_t watchdogPl = 0; - uint8_t watchdogInt = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&watchdogPs, &data_field_ptr, &serializedSize, - sizeof(watchdogPs), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&watchdogPl, &data_field_ptr, &serializedSize, - sizeof(watchdogPl), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&watchdogInt, &data_field_ptr, &serializedSize, - sizeof(watchdogInt), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the command to set the timeout of one of the three watchdogs (PS, - * PL, INT) - */ -class WatchdogsConfigTimeout: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param watchdogPs Selects the watchdog to configure (0 - PS, 1 - PL, 2 - INT) - * @param timeout The timeout to set - */ - WatchdogsConfigTimeout(uint8_t watchdog, uint32_t timeout) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_WTD_CONFIG_TIMEOUT, - DEFAULT_SEQUENCE_COUNT), watchdog(watchdog), timeout(timeout) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 7; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t watchdog = 0; - uint32_t timeout = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&watchdog, &data_field_ptr, &serializedSize, - sizeof(watchdog), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&timeout, &data_field_ptr, &serializedSize, - sizeof(timeout), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the command to enable of disable the latchup alert. - * - * @details There are 7 different latchup alerts. - */ -class LatchupAlert: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param state true - enable, false - disable - * @param latchupId Identifies the latchup to enable/disable (0 - 0.85V, 1 - 1.8V, 2 - MISC, - * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) - */ - LatchupAlert(bool state, uint8_t latchupId) : - SpacePacket(DATA_FIELD_LENGTH - 1, true), latchupId(latchupId) { - if (state) { - this->setAPID(APID_ENABLE_LATCHUP_ALERT); - } else { - this->setAPID(APID_DISABLE_LATCHUP_ALERT); - } - this->setPacketSequenceCount(DEFAULT_SEQUENCE_COUNT); - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 3; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t latchupId = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, - sizeof(latchupId), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the command to calibrate a certain latchup alert. - */ -class AutoCalibrateAlert: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param latchupId Identifies the latchup alert to calibrate (0 - 0.85V, 1 - 1.8V, 2 - MISC, - * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) - * @param mg - */ - AutoCalibrateAlert(uint8_t latchupId, uint32_t mg) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_AUTO_CALIBRATE_ALERT, - DEFAULT_SEQUENCE_COUNT), latchupId(latchupId), mg(mg) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 7; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t latchupId = 0; - uint32_t mg = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, - sizeof(latchupId), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&mg, &data_field_ptr, &serializedSize, - sizeof(mg), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - - -class SetAlertlimit: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param latchupId Identifies the latchup alert to calibrate (0 - 0.85V, 1 - 1.8V, 2 - MISC, - * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) - * @param dutycycle - */ - SetAlertlimit(uint8_t latchupId, uint32_t dutycycle) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ALERT_LIMIT, - DEFAULT_SEQUENCE_COUNT), latchupId(latchupId), dutycycle(dutycycle) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 7; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t latchupId = 0; - uint32_t dutycycle = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, - sizeof(latchupId), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&dutycycle, &data_field_ptr, &serializedSize, - sizeof(dutycycle), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -class SetAlertIrqFilter: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param latchupId Identifies the latchup alert to calibrate (0 - 0.85V, 1 - 1.8V, 2 - MISC, - * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) - * @param tp - * @param div - */ - SetAlertIrqFilter(uint8_t latchupId, uint8_t tp, uint8_t div) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ALERT_IRQ_FILTER, - DEFAULT_SEQUENCE_COUNT), tp(tp), div(div) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 5; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t latchupId = 0; - uint8_t tp = 0; - uint8_t div = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, - sizeof(latchupId), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&tp, &data_field_ptr, &serializedSize, - sizeof(tp), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&div, &data_field_ptr, &serializedSize, - sizeof(div), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - - -/** - * @brief This class packages the space packet to set the sweep period of the ADC. - */ -class SetAdcSweepPeriod: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param sweepPeriod Sweep period in us. minimum is 21 us - */ - SetAdcSweepPeriod(uint32_t sweepPeriod) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_SWEEP_PERIOD, - DEFAULT_SEQUENCE_COUNT), sweepPeriod(sweepPeriod) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 6; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint32_t sweepPeriod = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&sweepPeriod, &data_field_ptr, &serializedSize, - sizeof(sweepPeriod), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet to enable or disable ADC channels. - */ -class SetAdcEnabledChannels: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param ch Defines channels to be enabled or disabled. - */ - SetAdcEnabledChannels(uint16_t ch) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_ENABLED_CHANNELS, - DEFAULT_SEQUENCE_COUNT), ch(ch) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 4; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint16_t ch = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&ch, &data_field_ptr, &serializedSize, - sizeof(ch), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet to configures the window size and striding step of - * the moving average filter applied to the ADC readings. - */ -class SetAdcWindowAndStride: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param windowSize - * @param stridingStepSize - */ - SetAdcWindowAndStride(uint16_t windowSize, uint16_t stridingStepSize) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_WINDOW_AND_STRIDE, - DEFAULT_SEQUENCE_COUNT), windowSize(windowSize), stridingStepSize( - stridingStepSize) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 6; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint16_t windowSize = 0; - uint16_t stridingStepSize = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&windowSize, &data_field_ptr, &serializedSize, - sizeof(windowSize), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&stridingStepSize, &data_field_ptr, &serializedSize, - sizeof(stridingStepSize), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet to set the ADC trigger threshold. - */ -class SetAdcThreshold: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param threshold - */ - SetAdcThreshold(uint32_t threshold) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_THRESHOLD, - DEFAULT_SEQUENCE_COUNT), threshold(threshold) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 6; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint32_t threshold = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&threshold, &data_field_ptr, &serializedSize, - sizeof(threshold), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet to select between NVM 0 and NVM 1. - */ -class SelectNvm: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param mem 0 - select NVM0, 1 - select NVM1. - */ - SelectNvm(uint8_t mem) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SELECT_NVM, - DEFAULT_SEQUENCE_COUNT), mem(mem) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 3; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t mem = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&mem, &data_field_ptr, &serializedSize, - sizeof(mem), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet to power the NVMs on or off. - */ -class EnableNvms: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param n01 Set to one to power NVM0 and NVM1 on. 0 powers off memory. - * @param n3 Set to one to power NVM3 on. 0 powers off the memory. - */ - EnableNvms(uint8_t n01, uint8_t n3) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_ENABLE_NVMS, - DEFAULT_SEQUENCE_COUNT), n01(n01), n3(n3) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 4; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t n01 = 0; - uint8_t n3 = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&n01, &data_field_ptr, &serializedSize, - sizeof(n01), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&n3, &data_field_ptr, &serializedSize, - sizeof(n3), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet to run auto EM tests. - */ -class RunAutoEmTests: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param test 1 - complete EM test, 2 - Short test (only memory readback NVM0,1,3) - */ - RunAutoEmTests(uint8_t test) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_RUN_AUTO_EM_TESTS, - DEFAULT_SEQUENCE_COUNT), test(test) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 3; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t test = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&test, &data_field_ptr, &serializedSize, - sizeof(test), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet causing the supervisor to print the CPU load to - * the debug output. - */ -class PrintCpuStats: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param en Print is enabled if en != 0 - */ - PrintCpuStats(uint8_t en) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_PRINT_CPU_STATS, - DEFAULT_SEQUENCE_COUNT), en(en) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 3; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t en = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&en, &data_field_ptr, &serializedSize, - sizeof(en), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet to set the print verbosity in the supervisor - * software. - */ -class SetDbgVerbosity: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param vb 0: None, 1: Error, 2: Warn, 3: Info - */ - SetDbgVerbosity(uint8_t vb) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_DBG_VERBOSITY, - DEFAULT_SEQUENCE_COUNT), vb(vb) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 3; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t vb = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&vb, &data_field_ptr, &serializedSize, - sizeof(vb), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - - -/** - * @brief This class packages the space packet to wipe or dump parts of the MRAM. - */ -class MramCmd: public SpacePacket { -public: - - enum class MramAction { - WIPE, - DUMP - }; - - /** - * @brief Constructor - * - * @param start Start address of the MRAM section to wipe or dump - * @param stop End address of the MRAM section to wipe or dump - * @param action Dump or wipe MRAM - * - * @note The content at the stop address is excluded from the dump or wipe operation. - */ - MramCmd(uint32_t start, uint32_t stop, MramAction action) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_IDLE_PACKET, - DEFAULT_SEQUENCE_COUNT), start(start), stop(stop) { - if(action == MramAction::WIPE) { - this->setAPID(APID_WIPE_MRAM); - } - else if (action == MramAction::DUMP) { - this->setAPID(APID_DUMP_MRAM); - } - else { - sif::debug << "WipeMram: Invalid action specified"; - } - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 8; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint32_t start = 0; - uint32_t stop = 0; - - void initPacket() { - uint8_t concatBuffer[6]; - concatBuffer[0] = static_cast(start >> 16); - concatBuffer[1] = static_cast(start >> 8); - concatBuffer[2] = static_cast(start); - concatBuffer[3] = static_cast(stop >> 16); - concatBuffer[4] = static_cast(stop >> 8); - concatBuffer[5] = static_cast(stop); - uint8_t* data_field_ptr = this->localData.fields.buffer; - std::memcpy(data_field_ptr, concatBuffer, sizeof(concatBuffer)); - size_t serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet change the state of a GPIO. This command is only - * required for ground testing. - */ -class SetGpio: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param port - * @param pin - * @param val - */ - SetGpio(uint8_t port, uint8_t pin, uint8_t val) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_GPIO, - DEFAULT_SEQUENCE_COUNT), port(port), pin(pin), val(val) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 5; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t port = 0; - uint8_t pin = 0; - uint8_t val = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&port, &data_field_ptr, &serializedSize, - sizeof(port), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&pin, &data_field_ptr, &serializedSize, - sizeof(pin), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&val, &data_field_ptr, &serializedSize, - sizeof(val), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet causing the supervisor print the state of a GPIO - * to the debug output. - */ -class ReadGpio: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param port - * @param pin - */ - ReadGpio(uint8_t port, uint8_t pin) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_READ_GPIO, - DEFAULT_SEQUENCE_COUNT), port(port), pin(pin) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 4; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t port = 0; - uint8_t pin = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&port, &data_field_ptr, &serializedSize, - sizeof(port), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&pin, &data_field_ptr, &serializedSize, - sizeof(pin), SerializeIF::Endianness::BIG); - serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet to perform the factory reset. The op parameter is - * optional. - * - * @details: Without OP: All MRAM entries will be cleared. - * OP = 0x01: Only the mirror entries will be wiped. - * OP = 0x02: Only the circular entries will be wiped. - */ -class FactoryReset: public SpacePacket { -public: - - enum class Op { - CLEAR_ALL, - MIRROR_ENTRIES, - CIRCULAR_ENTRIES - }; - - /** - * @brief Constructor - * - * @param op - */ - FactoryReset(Op op) : - SpacePacket(0, true, APID_FACTORY_RESET, - DEFAULT_SEQUENCE_COUNT), op(op) { - initPacket(); - } - -private: - - uint16_t packetLen = 1; // only CRC in data field - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - uint8_t crcOffset = 0; - - Op op = Op::CLEAR_ALL; - - void initPacket() { - - uint8_t* data_field_ptr = this->localData.fields.buffer; - - switch(op) { - case Op::MIRROR_ENTRIES: - *data_field_ptr = 1; - packetLen = 2; - crcOffset = 1; - break; - case Op::CIRCULAR_ENTRIES: - *data_field_ptr = 2; - packetLen = 2; - crcOffset = 1; - break; - default: - break; - } - this->setPacketDataLength(packetLen); - size_t serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + packetLen - 1); - uint8_t* crcPos = this->localData.fields.buffer + crcOffset; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - -class SupvTcSpacePacket : public SpacePacket { -public: - SupvTcSpacePacket(size_t payloadDataLen, uint16_t apid) : - SpacePacket(payloadDataLen + 1, true, apid, - DEFAULT_SEQUENCE_COUNT), payloadDataLen(payloadDataLen) { - } - - void makeCrc() { - size_t serializedSize = 0; - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + payloadDataLen); - uint8_t* crcPos = this->localData.fields.buffer + payloadDataLen; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } - -private: - // The sequence count of most of the TC packets for the supervisor is 1. - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - // The size of the payload data (data field without crc size) - size_t payloadDataLen = 0; -}; - -/** - * @brief This class can be used to package the update available or update verify command. - */ -class UpdateInfo: public SupvTcSpacePacket { -public: - - /** - * @brief Constructor - * - * @param apid Packet can be used to generate the update available and the update verify - * packet. Thus the APID must be specified here. - * @param image The image to update on a NVM (A - 0, B - 1) - * @param partition The partition to update. uboot - 1, bitstream - 2, linux - 3, - * application - 4 - * @param imageSize The size of the update image - * param numPackets The number of space packets required to transfer all data. - */ - UpdateInfo(uint16_t apid, uint8_t image, uint8_t partition, uint32_t imageSize, - uint32_t imageCrc, uint32_t numPackets) : - SupvTcSpacePacket(PAYLOAD_LENGTH, apid), image(image), partition(partition), imageSize( - imageSize), imageCrc(imageCrc), numPackets(numPackets) { - initPacket(); - makeCrc(); - } - -private: - - static const uint16_t PAYLOAD_LENGTH = 14; // length without CRC field - - uint8_t image = 0; - uint8_t partition = 0; - uint32_t imageSize = 0; - uint32_t imageCrc = 0; - uint32_t numPackets = 0; - - void initPacket() { - size_t serializedSize = 0; - uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(&image, &data_field_ptr, &serializedSize, - sizeof(image), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&partition, &data_field_ptr, &serializedSize, - sizeof(partition), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&imageSize, &data_field_ptr, &serializedSize, - sizeof(imageSize), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&imageCrc, &data_field_ptr, &serializedSize, - sizeof(imageCrc), SerializeIF::Endianness::BIG); - serializedSize = 0; - SerializeAdapter::serialize(&numPackets, &data_field_ptr, &serializedSize, - sizeof(numPackets), SerializeIF::Endianness::BIG); - } -}; - -/** - * @brief This class packages the space packet transporting a part of an MPSoC update. - */ -class UpdatePacket: public SupvTcSpacePacket { -public: - - /** - * @brief Constructor - * - * @param payloadLength Update data length (data field length without CRC) - */ - UpdatePacket(uint16_t payloadLength) : - SupvTcSpacePacket(payloadLength, APID_UPDATE_IMAGE_DATA) { - } - - /** - * @brief Returns the pointer to the beginning of the data field. - */ - uint8_t* getDataFieldPointer() { - return this->localData.fields.buffer; - } -}; - -/** - * @brief This dataset stores the boot status report of the supervisor. - */ -class BootStatusReport: public StaticLocalDataSet { -public: - - BootStatusReport(HasLocalDataPoolIF* owner) : - StaticLocalDataSet(owner, BOOT_REPORT_SET_ID) { - } - - BootStatusReport(object_id_t objectId) : - StaticLocalDataSet(sid_t(objectId, BOOT_REPORT_SET_ID)) { - } - - /** Information about boot status of MPSoC */ - lp_var_t bootSignal = lp_var_t(sid.objectId, PoolIds::BOOT_SIGNAL, this); - lp_var_t resetCounter = lp_var_t(sid.objectId, PoolIds::RESET_COUNTER, this); - /** Time the MPSoC needs for last boot */ - lp_var_t bootAfterMs = lp_var_t(sid.objectId, PoolIds::BOOT_AFTER_MS, this); - /** The currently set boot timeout */ - lp_var_t bootTimeoutMs = lp_var_t(sid.objectId, PoolIds::BOOT_TIMEOUT_MS, this); - lp_var_t activeNvm = lp_var_t(sid.objectId, PoolIds::ACTIVE_NVM, this); - /** States of the boot partition pins */ - lp_var_t bp0State = lp_var_t(sid.objectId, PoolIds::BP0_STATE, this); - lp_var_t bp1State = lp_var_t(sid.objectId, PoolIds::BP1_STATE, this); - lp_var_t bp2State = lp_var_t(sid.objectId, PoolIds::BP2_STATE, this); -}; - -/** - * @brief This dataset stores the housekeeping data of the supervisor. - */ -class HkSet: public StaticLocalDataSet { -public: - - HkSet(HasLocalDataPoolIF* owner) : - StaticLocalDataSet(owner, HK_SET_ID) { - } - - HkSet(object_id_t objectId) : - StaticLocalDataSet(sid_t(objectId, HK_SET_ID)) { - } - - lp_var_t tempPs = lp_var_t(sid.objectId, PoolIds::TEMP_PS, this); - lp_var_t tempPl = lp_var_t(sid.objectId, PoolIds::TEMP_PS, this); - lp_var_t tempSup = lp_var_t(sid.objectId, PoolIds::TEMP_SUP, this); - lp_var_t uptime = lp_var_t(sid.objectId, PoolIds::UPTIME, this); - lp_var_t cpuLoad = lp_var_t(sid.objectId, PoolIds::CPULOAD, this); - lp_var_t availableHeap = lp_var_t(sid.objectId, PoolIds::AVAILABLEHEAP, - this); - lp_var_t numTcs = lp_var_t(sid.objectId, PoolIds::NUM_TCS, this); - lp_var_t numTms = lp_var_t(sid.objectId, PoolIds::NUM_TMS, this); - lp_var_t socState = lp_var_t(sid.objectId, PoolIds::SOC_STATE, this); - lp_var_t nvm0_1_state = lp_var_t(sid.objectId, PoolIds::NVM0_1_STATE, this); - lp_var_t nvm3_state = lp_var_t(sid.objectId, PoolIds::NVM3_STATE, this); - lp_var_t missionIoState = lp_var_t(sid.objectId, PoolIds::MISSION_IO_STATE, - this); - lp_var_t fmcState = lp_var_t(sid.objectId, PoolIds::FMC_STATE, this); -}; - -/** - * @brief This dataset stores the last requested latchup status report. - */ -class LatchupStatusReport: public StaticLocalDataSet { -public: - - LatchupStatusReport(HasLocalDataPoolIF* owner) : - StaticLocalDataSet(owner, LATCHUP_RPT_ID) { - } - - LatchupStatusReport(object_id_t objectId) : - StaticLocalDataSet(sid_t(objectId, LATCHUP_RPT_ID)) { - } - - lp_var_t id = lp_var_t(sid.objectId, PoolIds::LATCHUP_ID, this); - lp_var_t cnt0 = lp_var_t(sid.objectId, PoolIds::CNT0, this); - lp_var_t cnt1 = lp_var_t(sid.objectId, PoolIds::CNT1, this); - lp_var_t cnt2 = lp_var_t(sid.objectId, PoolIds::CNT2, this); - lp_var_t cnt3 = lp_var_t(sid.objectId, PoolIds::CNT3, this); - lp_var_t cnt4 = lp_var_t(sid.objectId, PoolIds::CNT4, this); - lp_var_t cnt5 = lp_var_t(sid.objectId, PoolIds::CNT5, this); - lp_var_t cnt6 = lp_var_t(sid.objectId, PoolIds::CNT6, this); - lp_var_t timeSec = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_SEC, this); - lp_var_t timeMin = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MIN, this); - lp_var_t timeHour = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_HOUR, this); - lp_var_t timeDay = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_DAY, this); - lp_var_t timeMon = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MON, this); - lp_var_t timeYear = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_YEAR, this); - lp_var_t timeMsec = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MSEC, this); - lp_var_t isSet = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_IS_SET, this); -}; -} - -#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_ */ diff --git a/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.cpp b/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.cpp deleted file mode 100644 index 4e7c9458..00000000 --- a/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "ArcsecDatalinkLayer.h" - -ArcsecDatalinkLayer::ArcsecDatalinkLayer() { - slipInit(); -} - -ArcsecDatalinkLayer::~ArcsecDatalinkLayer() { -} - -void ArcsecDatalinkLayer::slipInit() { - slipInfo.buffer = rxBuffer; - slipInfo.maxlength = StarTracker::MAX_FRAME_SIZE; - slipInfo.length = 0; - slipInfo.unescape_next = 0; - slipInfo.prev_state = SLIP_COMPLETE; -} - -ReturnValue_t ArcsecDatalinkLayer::decodeFrame(const uint8_t* rawData, size_t rawDataSize, - size_t* bytesLeft) { - size_t bytePos = 0; - for (bytePos = 0; bytePos < rawDataSize; bytePos++) { - enum arc_dec_result decResult = arc_transport_decode_body(*(rawData + bytePos), &slipInfo, - decodedFrame, &decFrameSize); - *bytesLeft = rawDataSize - bytePos - 1; - switch (decResult) { - case ARC_DEC_INPROGRESS: { - if (bytePos == rawDataSize - 1) { - return DEC_IN_PROGRESS; - } - continue; - } - case ARC_DEC_ERROR_FRAME_SHORT: - return REPLY_TOO_SHORT; - case ARC_DEC_ERROR_CHECKSUM: - return CRC_FAILURE; - case ARC_DEC_ASYNC: - case ARC_DEC_SYNC: { - // Reset length of SLIP struct for next frame - slipInfo.length = 0; - return RETURN_OK; - } - default: - sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl; - break; - return RETURN_FAILED; - } - } - return RETURN_FAILED; -} - -uint8_t ArcsecDatalinkLayer::getReplyFrameType() { - return decodedFrame[0]; -} - -const uint8_t* ArcsecDatalinkLayer::getReply() { - return &decodedFrame[1]; -} - -void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, uint32_t length) { - arc_transport_encode_body(data, length, encBuffer, &encFrameSize); -} - -uint8_t* ArcsecDatalinkLayer::getEncodedFrame() { - return encBuffer; -} - -uint32_t ArcsecDatalinkLayer::getEncodedLength() { - return encFrameSize; -} - -uint8_t ArcsecDatalinkLayer::getStatusField() { - return *(decodedFrame + STATUS_OFFSET); -} - -uint8_t ArcsecDatalinkLayer::getId() { - return *(decodedFrame + ID_OFFSET); -} - diff --git a/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.h b/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.h deleted file mode 100644 index a65881c7..00000000 --- a/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ -#define BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ - -#include "StarTrackerDefinitions.h" -#include "fsfw/returnvalues/HasReturnvaluesIF.h" - -extern "C" { - #include "common/misc.h" -} - -/** - * @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec. - */ -class ArcsecDatalinkLayer: public HasReturnvaluesIF { -public: - - static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER; - - //! [EXPORT] : [COMMENT] More data required to complete frame - static const ReturnValue_t DEC_IN_PROGRESS = MAKE_RETURN_CODE(0xA0); - //! [EXPORT] : [COMMENT] Data too short to represent a valid frame - static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1); - //! [EXPORT] : [COMMENT] Detected CRC failure in received frame - static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2); - - static const uint8_t STATUS_OK = 0; - - ArcsecDatalinkLayer(); - virtual ~ArcsecDatalinkLayer(); - - /** - * @brief Applies decoding to data referenced by rawData pointer - * - * @param rawData Pointer to raw data received from star tracker - * @param rawDataSize Size of raw data stream - * @param remainingBytes Number of bytes left - */ - ReturnValue_t decodeFrame(const uint8_t* rawData, size_t rawDataSize, size_t* bytesLeft); - - /** - * @brief SLIP encodes data pointed to by data pointer. - * - * @param data Pointer to data to encode - * @param length Length of buffer to encode - */ - void encodeFrame(const uint8_t* data, uint32_t length); - - /** - * @brief Returns the frame type field of a decoded frame. - */ - uint8_t getReplyFrameType(); - - /** - * @brief Returns pointer to reply packet (first entry normally action ID, telemetry ID etc.) - */ - const uint8_t* getReply(); - - /** - * @brief Returns size of encoded frame - */ - uint32_t getEncodedLength(); - - /** - * @brief Returns pointer to encoded frame - */ - uint8_t* getEncodedFrame(); - - /** - * @brief Returns status of reply - */ - uint8_t getStatusField(); - - /** - * @brief Returns ID of reply - */ - uint8_t getId(); - -private: - - static const uint8_t ID_OFFSET = 1; - static const uint8_t STATUS_OFFSET = 2; - - // Used by arcsec slip decoding function process received data - uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE]; - // Decoded frame will be copied to this buffer - uint8_t decodedFrame[StarTracker::MAX_FRAME_SIZE]; - // Buffer where encoded frames will be stored. First byte of encoded frame represents type of - // reply - uint8_t encBuffer[StarTracker::MAX_FRAME_SIZE * 2 + 2]; - // Size of decoded frame - uint32_t decFrameSize = 0; - // Size of encoded frame - uint32_t encFrameSize = 0; - - slip_decode_state slipInfo; - - void slipInit(); -}; - -#endif /* BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ */ diff --git a/bsp_q7s/devices/startracker/ArcsecJsonKeys.h b/bsp_q7s/devices/startracker/ArcsecJsonKeys.h deleted file mode 100644 index 2c598b43..00000000 --- a/bsp_q7s/devices/startracker/ArcsecJsonKeys.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ -#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ - -/** - * @brief Keys used in JSON file of ARCSEC. - */ -namespace arcseckeys { - static const char PROPERTIES[] = "properties"; - static const char NAME[] = "name"; - static const char VALUE[] = "value"; - - static const char LIMITS[] = "limits"; - static const char ACTION[] = "action"; - static const char FPGA18CURRENT[] = "FPGA18Current"; - static const char FPGA25CURRENT[] = "FPGA25Current"; - static const char FPGA10CURRENT[] = "FPGA10Current"; - static const char MCUCURRENT[] = "MCUCurrent"; - static const char CMOS21CURRENT[] = "CMOS21Current"; - static const char CMOSPIXCURRENT[] = "CMOSPixCurrent"; - static const char CMOS33CURRENT[] = "CMOS33Current"; - static const char CMOSVRESCURRENT[] = "CMOSVResCurrent"; - static const char CMOS_TEMPERATURE[] = "CMOSTemperature"; - static const char MCU_TEMPERATURE[] = "MCUTemperature"; - - static const char MOUNTING[] = "mounting"; - static const char qw[] = "qw"; - static const char qx[] = "qx"; - static const char qy[] = "qy"; - static const char qz[] = "qz"; - - static const char CAMERA[] = "camera"; - static const char MODE[] = "mode"; - static const char FOCALLENGTH[] = "focallength"; - static const char EXPOSURE[] = "exposure"; - static const char INTERVAL[] = "interval"; - static const char OFFSET[] = "offset"; - static const char PGAGAIN[] = "PGAGain"; - static const char ADCGAIN[] = "ADCGain"; - static const char REG_1[] = "reg1"; - static const char VAL_1[] = "val1"; - static const char REG_2[] = "reg2"; - static const char VAL_2[] = "val2"; - static const char REG_3[] = "reg3"; - static const char VAL_3[] = "val3"; - static const char REG_4[] = "reg4"; - static const char VAL_4[] = "val4"; - static const char REG_5[] = "reg5"; - static const char VAL_5[] = "val5"; - static const char REG_6[] = "reg6"; - static const char VAL_6[] = "val6"; - static const char REG_7[] = "reg7"; - static const char VAL_7[] = "val7"; - static const char REG_8[] = "reg8"; - static const char VAL_8[] = "val8"; - static const char FREQ_1[] = "freq1"; - static const char FREQ_2[] = "freq2"; - - static const char BLOB[] = "blob"; - static const char MIN_VALUE[] = "minValue"; - static const char MIN_DISTANCE[] = "minDistance"; - static const char NEIGHBOUR_DISTANCE[] = "neighbourDistance"; - static const char NEIGHBOUR_BRIGHT_PIXELS[] = "neighbourBrightPixels"; - static const char MIN_TOTAL_VALUE[] = "minTotalValue"; - static const char MAX_TOTAL_VALUE[] = "maxTotalValue"; - static const char MIN_BRIGHT_NEIGHBOURS[] = "minBrightNeighbours"; - static const char MAX_BRIGHT_NEIGHBOURS[] = "maxBrightNeighbours"; - static const char MAX_PIXEL_TO_CONSIDER[] = "maxPixelsToConsider"; - static const char SIGNAL_THRESHOLD[] = "signalThreshold"; - static const char DARK_THRESHOLD[] = "darkThreshold"; - static const char ENABLE_HISTOGRAM[] = "enableHistogram"; - static const char ENABLE_CONTRAST[] = "enableContrast"; - static const char BIN_MODE[] = "binMode"; - - static const char CENTROIDING[] = "centroiding"; - static const char ENABLE_FILTER[] = "enableFilter"; - static const char MAX_QUALITY[] = "maxquality"; - static const char MIN_QUALITY[] = "minquality"; - static const char MAX_INTENSITY[] = "maxintensity"; - static const char MIN_INTENSITY[] = "minintensity"; - static const char MAX_MAGNITUDE[] = "maxmagnitude"; - static const char GAUSSIAN_CMAX[] = "gaussianCmax"; - static const char GAUSSIAN_CMIN[] = "gaussianCmin"; - static const char TRANSMATRIX_00[] = "transmatrix00"; - static const char TRANSMATRIX_01[] = "transmatrix01"; - static const char TRANSMATRIX_10[] = "transmatrix10"; - static const char TRANSMATRIX_11[] = "transmatrix11"; - - static const char LISA[] = "lisa"; - static const char PREFILTER_DIST_THRESHOLD[] = "prefilterDistThreshold"; - static const char PREFILTER_ANGLE_THRESHOLD[] = "prefilterAngleThreshold"; - static const char FOV_WIDTH[] = "fov_width"; - static const char FOV_HEIGHT[] = "fov_height"; - static const char FLOAT_STAR_LIMIT[] = "float_star_limit"; - static const char CLOSE_STAR_LIMIT[] = "close_star_limit"; - static const char RATING_WEIGHT_CLOSE_STAR_COUNT[] = "rating_weight_close_star_count"; - static const char RATING_WEIGHT_FRACTION_CLOSE[] = "rating_weight_fraction_close"; - static const char RATING_WEIGHT_MEAN_SUM[] = "rating_weight_mean_sum"; - static const char RATING_WEIGHT_DB_STAR_COUNT[] = "rating_weight_db_star_count"; - static const char MAX_COMBINATIONS[] = "max_combinations"; - static const char NR_STARS_STOP[] = "nr_stars_stop"; - static const char FRACTION_CLOSE_STOP[] = "fraction_close_stop"; - - static const char MATCHING[] = "matching"; - static const char SQUARED_DISTANCE_LIMIT[] = "squaredDistanceLimit"; - static const char SQUARED_SHIFT_LIMIT[] = "squaredShiftLimit"; - - static const char VALIDATION[] = "validation"; - static const char STABLE_COUNT[] = "stable_count"; - static const char MAX_DIFFERENCE[] = "max_difference"; - static const char MIN_TRACKER_CONFIDENCE[] = "min_trackerConfidence"; - static const char MIN_MATCHED_STARS[] = "min_matchedStars"; - - static const char TRACKING[] = "tracking"; - static const char THIN_LIMIT[] = "thinLimit"; - static const char OUTLIER_THRESHOLD[] = "outlierThreshold"; - static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST"; - static const char TRACKER_CHOICE[] = "trackerChoice"; - - static const char ALGO[] = "algo"; - static const char L2T_MIN_CONFIDENCE[] = "l2t_minConfidence"; - static const char L2T_MIN_MATCHED[] = "l2t_minConfidence"; - static const char T2L_MIN_CONFIDENCE[] = "t2l_minConfidence"; - static const char T2L_MIN_MATCHED[] = "t2l_minMatched"; -} - -#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ */ diff --git a/bsp_q7s/devices/startracker/ArcsecJsonParamBase.cpp b/bsp_q7s/devices/startracker/ArcsecJsonParamBase.cpp deleted file mode 100644 index 339c3fe7..00000000 --- a/bsp_q7s/devices/startracker/ArcsecJsonParamBase.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "ArcsecJsonParamBase.h" -#include "ArcsecJsonKeys.h" - -ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {} - -ReturnValue_t ArcsecJsonParamBase::create(std::string fullname, uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - result = init(fullname); - if (result != RETURN_OK) { - return result; - } - result = createCommand(buffer); - return result; -} - -ReturnValue_t ArcsecJsonParamBase::getParam(const std::string name, std::string& value) { - for (json::iterator it = set.begin(); it != set.end(); ++it) { - if ((*it)[arcseckeys::NAME] == name) { - value = (*it)[arcseckeys::VALUE]; - convertEmpty(value); - return RETURN_OK; - } - } - return PARAM_NOT_EXISTS; -} - -void ArcsecJsonParamBase::convertEmpty(std::string& value) { - if (value == "") { - value = "0"; - } -} - -void ArcsecJsonParamBase::addfloat(const std::string value, uint8_t* buffer) { - float param = std::stof(value); - std::memcpy(buffer, ¶m, sizeof(param)); -} - -void ArcsecJsonParamBase::adduint8(const std::string value, uint8_t* buffer) { - uint8_t param = std::stoi(value); - std::memcpy(buffer, ¶m, sizeof(param)); -} - -void ArcsecJsonParamBase::addint16(const std::string value, uint8_t* buffer) { - int16_t param = std::stoi(value); - std::memcpy(buffer, ¶m, sizeof(param)); -} - -void ArcsecJsonParamBase::adduint16(const std::string value, uint8_t* buffer) { - uint16_t param = std::stoi(value); - std::memcpy(buffer, ¶m, sizeof(param)); -} - -void ArcsecJsonParamBase::adduint32(const std::string value, uint8_t* buffer) { - uint32_t param = std::stoi(value); - std::memcpy(buffer, ¶m, sizeof(param)); -} - -void ArcsecJsonParamBase::addSetParamHeader(uint8_t* buffer, uint8_t setId) { - *buffer = static_cast(TMTC_SETPARAMREQ); - *(buffer + 1) = setId; -} - -ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) { - ReturnValue_t result = RETURN_OK; - if (not std::filesystem::exists(filename)) { - sif::warning << "ArcsecJsonParamBase::init: JSON file " << filename << " does not exist" - << std::endl; - return JSON_FILE_NOT_EXISTS; - } - createJsonObject(filename); - result = initSet(); - if (result != RETURN_OK) { - return result; - } - return RETURN_OK; -} - -void ArcsecJsonParamBase::createJsonObject(const std::string fullname) { - json j; - std::ifstream file(fullname); - file >> j; - file.close(); - properties = j[arcseckeys::PROPERTIES]; -} - -ReturnValue_t ArcsecJsonParamBase::initSet() { - for (json::iterator it = properties.begin(); it != properties.end(); ++it) { - if ((*it)["name"] == setName) { - set = (*it)["fields"]; - return RETURN_OK; - } - } - return SET_NOT_EXISTS; -} diff --git a/bsp_q7s/devices/startracker/ArcsecJsonParamBase.h b/bsp_q7s/devices/startracker/ArcsecJsonParamBase.h deleted file mode 100644 index 320eff53..00000000 --- a/bsp_q7s/devices/startracker/ArcsecJsonParamBase.h +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ -#define BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ - -#include -#include -#include - -#include "fsfw/returnvalues/HasReturnvaluesIF.h" -#include "StarTrackerDefinitions.h" - -extern "C" { - #include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h" - #include "thirdparty/arcsec_star_tracker/common/genericstructs.h" -} - -using json = nlohmann::json; - -/** - * @brief Base class for creation of parameter configuration commands. Reads parameter set - * from a json file located on the filesystem and generates the appropriate command - * to apply the parameters to the star tracker software. - * - * @author J. Meier - */ -class ArcsecJsonParamBase : public HasReturnvaluesIF { -public: - - static const uint8_t INTERFACE_ID = CLASS_ID::ARCSEC_JSON_BASE; - //! [EXPORT] : [COMMENT] Specified json file does not exist - static const ReturnValue_t JSON_FILE_NOT_EXISTS = MAKE_RETURN_CODE(1); - //! [EXPORT] : [COMMENT] Requested set does not exist in json file - static const ReturnValue_t SET_NOT_EXISTS = MAKE_RETURN_CODE(2); - //! [EXPORT] : [COMMENT] Requested parameter does not exist in json file - static const ReturnValue_t PARAM_NOT_EXISTS = MAKE_RETURN_CODE(3); - - /** - * @brief Constructor - * - * @param fullname Name with absolute path of json file containing the parameters to set. - */ - ArcsecJsonParamBase(std::string setName); - - /** - * @brief Fills a buffer with a parameter set - * - * @param fullname The name including the absolute path of the json file containing the - * parameter set. - * @param buffer Pointer to the buffer the command will be written to - */ - ReturnValue_t create(std::string fullname, uint8_t* buffer); - - /** - * @brief Returns the size of the parameter command. - */ - virtual size_t getSize() = 0; - -protected: - - /** - * @brief Reads the value of a parameter from a json set - * - * @param name The name of the parameter - * @param value The string representation of the read value - * - * @return RETURN_OK if successful, otherwise PARAM_NOT_EXISTS - */ - ReturnValue_t getParam(const std::string name, std::string& value); - - /** - * @brief Converts empty string which is equal to define a value as zero. - */ - void convertEmpty(std::string& value); - - /** - * @brief This function adds a float represented as string to a buffer - * - * @param value The float in string representation to add - * @param buffer Pointer to the buffer the float will be written to - */ - void addfloat(const std::string value, uint8_t* buffer); - - /** - * @brief This function adds a uint8_t represented as string to a buffer - * - * @param value The uint8_t in string representation to add - * @param buffer Pointer to the buffer the uint8_t will be written to - */ - void adduint8(const std::string value, uint8_t* buffer); - - /** - * @brief This function adds a int16_t represented as string to a buffer - * - * @param value The int16_t in string representation to add - * @param buffer Pointer to the buffer the int16_t will be written to - */ - void addint16(const std::string value, uint8_t* buffer); - - /** - * @brief This function adds a uint16_t represented as string to a buffer - * - * @param value The uint16_t in string representation to add - * @param buffer Pointer to the buffer the uint16_t will be written to - */ - void adduint16(const std::string value, uint8_t* buffer); - - /** - * @brief This function adds a uint32_t represented as string to a buffer - * - * @param value The uint32_t in string representation to add - * @param buffer Pointer to the buffer the uint32_t will be written to - */ - void adduint32(const std::string value, uint8_t* buffer); - - void addSetParamHeader(uint8_t* buffer, uint8_t setId); - -private: - - json properties; - json set; - std::string setName; - - /** - * @brief This function must be implemented by the derived class to define creation of a - * parameter command. - */ - virtual ReturnValue_t createCommand(uint8_t* buffer) = 0; - - /** - * @brief Initializes the properties json object and the set json object - * - * @param fullname Name including absolute path to json file - * @param setName The name of the set to work on - * - * @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise - * RETURN_OK - */ - ReturnValue_t init(const std::string filename); - - void createJsonObject(const std::string fullname); - - /** - * @brief Extracts the json set object form the json file - * - * @param setName The name of the set to create the json object from - */ - ReturnValue_t initSet(); -}; - -#endif /* BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ */ diff --git a/bsp_q7s/devices/startracker/StarTrackerDefinitions.h b/bsp_q7s/devices/startracker/StarTrackerDefinitions.h deleted file mode 100644 index f1f7b7d0..00000000 --- a/bsp_q7s/devices/startracker/StarTrackerDefinitions.h +++ /dev/null @@ -1,1210 +0,0 @@ -#ifndef MISSION_STARTRACKER_DEFINITIONS_H_ -#define MISSION_STARTRACKER_DEFINITIONS_H_ - -#include -#include -#include -#include -#include "objects/systemObjectList.h" -#include - -namespace StarTracker { - -/** This is the address of the star tracker */ -static const uint8_t ADDRESS = 33; - -static const uint8_t STATUS_OK = 0; - -enum PoolIds: lp_id_t { - TICKS_TIME_SET, - TIME_TIME_SET, - RUN_TIME, - UNIX_TIME, - TICKS_VERSION_SET, - TIME_VERSION_SET, - PROGRAM, - MAJOR, - MINOR, - TICKS_INTERFACE_SET, - TIME_INTERFACE_SET, - FRAME_COUNT, - CHECKSUM_ERROR_COUNT, - SET_PARAM_COUNT, - SET_PARAM_REPLY_COUNT, - PARAM_REQUEST_COUNT, - PARAM_REPLY_COUNT, - REQ_TM_COUNT, - TM_REPLY_COUNT, - ACTION_REQ_COUNT, - ACTION_REPLY_COUNT, - TICKS_POWER_SET, - TIME_POWER_SET, - MCU_CURRENT, - MCU_VOLTAGE, - FPGA_CORE_CURRENT, - FPGA_CORE_VOLTAGE, - FPGA_18_CURRENT, - FPGA_18_VOLTAGE, - FPGA_25_CURRENT, - FPGA_25_VOLTAGE, - CMV_21_CURRENT, - CMV_21_VOLTAGE, - CMV_PIX_CURRENT, - CMV_PIX_VOLTAGE, - CMV_33_CURRENT, - CMV_33_VOLTAGE, - CMV_RES_CURRENT, - CMV_RES_VOLTAGE, - TICKS_TEMPERATURE_SET, - TIME_TEMPERATURE_SET, - MCU_TEMPERATURE, - CMOS_TEMPERATURE, - TICKS_SOLUTION_SET, - TIME_SOLUTION_SET, - CALI_QW, - CALI_QX, - CALI_QY, - CALI_QZ, - TRACK_CONFIDENCE, - TRACK_QW, - TRACK_QX, - TRACK_QY, - TRACK_QZ, - TRACK_REMOVED, - STARS_CENTROIDED, - STARS_MATCHED_DATABASE, - LISA_QW, - LISA_QX, - LISA_QY, - LISA_QZ, - LISA_PERC_CLOSE, - LISA_NR_CLOSE, - TRUST_WORTHY, - STABLE_COUNT, - SOLUTION_STRATEGY, - TICKS_HISTOGRAM_SET, - TIME_HISTOGRAM_SET, - HISTOGRAM_BINA0, - HISTOGRAM_BINA1, - HISTOGRAM_BINA2, - HISTOGRAM_BINA3, - HISTOGRAM_BINA4, - HISTOGRAM_BINA5, - HISTOGRAM_BINA6, - HISTOGRAM_BINA7, - HISTOGRAM_BINA8, - HISTOGRAM_BINB0, - HISTOGRAM_BINB1, - HISTOGRAM_BINB2, - HISTOGRAM_BINB3, - HISTOGRAM_BINB4, - HISTOGRAM_BINB5, - HISTOGRAM_BINB6, - HISTOGRAM_BINB7, - HISTOGRAM_BINB8, - HISTOGRAM_BINC0, - HISTOGRAM_BINC1, - HISTOGRAM_BINC2, - HISTOGRAM_BINC3, - HISTOGRAM_BINC4, - HISTOGRAM_BINC5, - HISTOGRAM_BINC6, - HISTOGRAM_BINC7, - HISTOGRAM_BINC8, - HISTOGRAM_BIND0, - HISTOGRAM_BIND1, - HISTOGRAM_BIND2, - HISTOGRAM_BIND3, - HISTOGRAM_BIND4, - HISTOGRAM_BIND5, - HISTOGRAM_BIND6, - HISTOGRAM_BIND7, - HISTOGRAM_BIND8, - TICKS_CONTRAST_SET, - TIME_CONTRAST_SET, - CONTRAST_BINA0, - CONTRAST_BINA1, - CONTRAST_BINA2, - CONTRAST_BINA3, - CONTRAST_BINA4, - CONTRAST_BINA5, - CONTRAST_BINA6, - CONTRAST_BINA7, - CONTRAST_BINA8, - CONTRAST_BINB0, - CONTRAST_BINB1, - CONTRAST_BINB2, - CONTRAST_BINB3, - CONTRAST_BINB4, - CONTRAST_BINB5, - CONTRAST_BINB6, - CONTRAST_BINB7, - CONTRAST_BINB8, - CONTRAST_BINC0, - CONTRAST_BINC1, - CONTRAST_BINC2, - CONTRAST_BINC3, - CONTRAST_BINC4, - CONTRAST_BINC5, - CONTRAST_BINC6, - CONTRAST_BINC7, - CONTRAST_BINC8, - CONTRAST_BIND0, - CONTRAST_BIND1, - CONTRAST_BIND2, - CONTRAST_BIND3, - CONTRAST_BIND4, - CONTRAST_BIND5, - CONTRAST_BIND6, - CONTRAST_BIND7, - CONTRAST_BIND8, - CHKSUM, - DWL_ID, - DWL_PIXX, - DWL_PIXY, - DWL_X_UNCORRECTED, - DWL_Y_UNCORRECTED, - DWL_X_CORRECTED, - DWL_Y_CORRECTED, - DWL_MAGNITUDE, - DWL_CXA, - DWL_CYA, - DWL_QUALITY, - MATCHEDSTR_ID, - MATCHEDSTR_CAMFPX, - MATCHEDSTR_CAMFPY, - MATCHEDSTR_CAMCARTX, - MATCHEDSTR_CAMCARTY, - MATCHEDSTR_CAMCARTZ, - MATCHEDSTR_CAMMAGNITUDE, - MATCHEDSTR_DBFPX, - MATCHEDSTR_DBFPY, - MATCHEDSTR_DBCARTX, - MATCHEDSTR_DBCARTY, - MATCHEDSTR_DBCARTZ, - MATCHEDSTR_DBMAGNITUDE, - MATCHEDSTR_CATALOGID, - DBIMAGE_ID, - DBIMAGE_PIXX, - DBIMAGE_PIXY, - DBIMAGE_X, - DBIMAGE_Y, - DBIMAGE_MAGNITUDE, - BLOBPIX_ID, - BLOBPIX_X, - BLOBPIX_Y, - BLOBPIX_TOT_VAL, - BLOBPIX_IN_USE, - BLOBPIX_BRIGHT_NEIGHBOURS, - BLOBPIX_REGION -}; - -static const DeviceCommandId_t PING_REQUEST = 0; -// Boots image (works only in bootloader mode) -static const DeviceCommandId_t BOOT = 1; -static const DeviceCommandId_t REQ_VERSION = 2; -static const DeviceCommandId_t REQ_INTERFACE = 3; -static const DeviceCommandId_t REQ_TIME = 4; -static const DeviceCommandId_t ERASE = 5; -static const DeviceCommandId_t UNLOCK = 6; -static const DeviceCommandId_t SWITCH_TO_BOOTLOADER_PROGRAM = 7; -static const DeviceCommandId_t DOWNLOAD_IMAGE = 9; -static const DeviceCommandId_t UPLOAD_IMAGE = 10; -static const DeviceCommandId_t REQ_POWER = 11; -static const DeviceCommandId_t TAKE_IMAGE = 15; -static const DeviceCommandId_t DOWNLOAD_CENTROID = 16; -static const DeviceCommandId_t UPLOAD_CENTROID = 17; -static const DeviceCommandId_t SUBSCRIBE_TO_TM = 18; -static const DeviceCommandId_t REQ_SOLUTION = 24; -static const DeviceCommandId_t REQ_TEMPERATURE = 25; -static const DeviceCommandId_t REQ_HISTOGRAM = 28; -static const DeviceCommandId_t REQ_CONTRAST = 29; -static const DeviceCommandId_t LIMITS = 40; -static const DeviceCommandId_t MOUNTING = 41; -static const DeviceCommandId_t CAMERA = 42; -static const DeviceCommandId_t BLOB = 43; -static const DeviceCommandId_t CENTROIDING = 44; -static const DeviceCommandId_t LISA = 45; -static const DeviceCommandId_t MATCHING = 46; -static const DeviceCommandId_t TRACKING = 47; -static const DeviceCommandId_t VALIDATION = 48; -static const DeviceCommandId_t ALGO = 49; -static const DeviceCommandId_t CHECKSUM = 50; -static const DeviceCommandId_t READ = 51; -static const DeviceCommandId_t WRITE = 52; -static const DeviceCommandId_t DOWNLOAD_MATCHED_STAR = 53; -static const DeviceCommandId_t STOP_IMAGE_LOADER = 55; -static const DeviceCommandId_t RESET_ERROR = 56; -static const DeviceCommandId_t CHANGE_DOWNLOAD_FILE = 57; -static const DeviceCommandId_t SET_JSON_FILE_NAME = 58; -static const DeviceCommandId_t SET_READ_FILENAME = 59; -static const DeviceCommandId_t SET_TIME = 60; -static const DeviceCommandId_t DOWNLOAD_DBIMAGE = 61; -static const DeviceCommandId_t DOWNLOAD_BLOBPIXEL = 62; -static const DeviceCommandId_t DOWNLOAD_FPGA_IMAGE = 63; -static const DeviceCommandId_t CHANGE_FPGA_DOWNLOAD_FILE = 64; -static const DeviceCommandId_t UPLOAD_FPGA_IMAGE = 65; -static const DeviceCommandId_t FPGA_ACTION = 66; -static const DeviceCommandId_t NONE = 0xFFFFFFFF; - -static const uint32_t VERSION_SET_ID = REQ_VERSION; -static const uint32_t INTERFACE_SET_ID = REQ_INTERFACE; -static const uint32_t POWER_SET_ID = REQ_POWER; -static const uint32_t TEMPERATURE_SET_ID = REQ_TEMPERATURE; -static const uint32_t TIME_SET_ID = REQ_TIME; -static const uint32_t SOLUTION_SET_ID = REQ_SOLUTION; -static const uint32_t HISTOGRAM_SET_ID = REQ_HISTOGRAM; -static const uint32_t CONTRAST_SET_ID = REQ_CONTRAST; -static const uint32_t CHECKSUM_SET_ID = CHECKSUM; -static const uint32_t DOWNLOADCENTROID_SET_ID = DOWNLOAD_CENTROID; -static const uint32_t DOWNLOAD_MATCHED_STAR_SET_ID = DOWNLOAD_MATCHED_STAR; -static const uint32_t DOWNLOAD_DBIMAGE_SET_ID = DOWNLOAD_DBIMAGE; -static const uint32_t DOWNLOAD_BLOBPIXEL_SET_ID = DOWNLOAD_BLOBPIXEL; - -/** Max size of unencoded frame */ -static const size_t MAX_FRAME_SIZE = 1200; - -static const uint8_t TEMPERATURE_SET_ENTRIES = 4; -static const uint8_t VERSION_SET_ENTRIES = 5; -static const uint8_t INTERFACE_SET_ENTRIES = 4; -static const uint8_t POWER_SET_ENTRIES = 18; -static const uint8_t TIME_SET_ENTRIES = 4; -static const uint8_t SOLUTION_SET_ENTRIES = 23; -static const uint8_t HISTOGRAM_SET_ENTRIES = 38; -static const uint8_t CONTRAST_SET_ENTRIES = 38; -static const uint8_t CHECKSUM_SET_ENTRIES = 1; -static const uint8_t DOWNLOAD_CENTROID_SET_ENTRIES = 11; -static const uint8_t DOWNLOAD_MATCHED_STAR_SET_ENTRIES = 14; -static const uint8_t DOWNLOAD_DBIMAGE_SET_ENTRIES = 6; -static const uint8_t DOWNLOAD_BLOBPIXEL_SET_ENTRIES = 7; - -// Action, parameter and telemetry IDs -namespace ID { - static const uint8_t PING = 0; - static const uint8_t BOOT = 1; - static const uint8_t VERSION = 2; - static const uint8_t INTERFACE = 3; - static const uint8_t LIMITS = 5; - static const uint8_t MOUNTING = 6; - static const uint8_t CAMERA = 9; - static const uint8_t BLOB = 10; - static const uint8_t CENTROIDING = 11; - static const uint8_t LISA = 12; - static const uint8_t MATCHING = 13; - static const uint8_t TRACKING = 14; - static const uint8_t VALIDATION = 15; - static const uint8_t ALGO = 16; - static const uint8_t REBOOT = 7; - static const uint8_t UPLOAD_IMAGE = 10; - static const uint8_t POWER = 11; - static const uint8_t SET_TIME = 14; - static const uint8_t SUBSCRIBE = 18; - static const uint8_t SOLUTION = 24; - static const uint8_t TEMPERATURE = 25; - static const uint8_t HISTOGRAM = 28; - static const uint8_t CONTRAST = 29; - static const uint8_t TIME = 1; - static const uint8_t WRITE = 2; - static const uint8_t READ = 3; - static const uint8_t CHECKSUM = 4; - static const uint8_t ERASE = 5; - static const uint8_t UNLOCK = 6; - static const uint8_t TAKE_IMAGE = 15; - static const uint8_t ERROR_RESET = 12; - static const uint8_t DOWNLOAD_CENTROID = 16; - static const uint8_t UPLOAD_CENTROID = 17; - static const uint8_t DOWNLOAD_MATCHED_STAR = 18; - static const uint8_t DOWNLOAD_DBIMAGE = 19; - static const uint8_t DOWNLOAD_BLOBPIXEL = 24; - static const uint8_t FPGA_ACTION = 22; -} - -namespace Program { - static const uint8_t BOOTLOADER = 1; - static const uint8_t FIRMWARE = 2; -} - -/** - * @brief This dataset can be used to store the temperature of a reaction wheel. - */ -class TemperatureSet: - public StaticLocalDataSet { -public: - - static const size_t SIZE = 20; - - TemperatureSet(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, TEMPERATURE_SET_ID) { - } - - TemperatureSet(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, TEMPERATURE_SET_ID)) { - } - - // Ticks is time reference generated by internal counter of the star tracker - lp_var_t ticks = lp_var_t(sid.objectId, - PoolIds::TICKS_TEMPERATURE_SET, this); - /** Unix time in microseconds */ - lp_var_t time = lp_var_t(sid.objectId, - PoolIds::TIME_TEMPERATURE_SET, this); - lp_var_t mcuTemperature = lp_var_t(sid.objectId, - PoolIds::MCU_TEMPERATURE, this); - lp_var_t cmosTemperature = lp_var_t(sid.objectId, - PoolIds::CMOS_TEMPERATURE, this); - - void printSet() { - sif::info << "TemperatureSet::printSet: Ticks: " - << this->ticks << std::endl; - sif::info << "TemperatureSet::printSet: Time: " - << this->time << " us" << std::endl; - sif::info << "TemperatureSet::printSet: MCU Temperature: " - << this->mcuTemperature << " °C" << std::endl; - sif::info << "TemperatureSet::printSet: CMOS Temperature: " - << this->cmosTemperature << " °C" << std::endl; - } -}; - -/** - * @brief Package to store version parameters - */ -class VersionSet: - public StaticLocalDataSet { -public: - - static const size_t SIZE = 15; - - VersionSet(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, VERSION_SET_ID) { - } - - VersionSet(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, VERSION_SET_ID)) { - } - - lp_var_t ticks = lp_var_t(sid.objectId, - PoolIds::TICKS_VERSION_SET, this); - /** Unix time in microseconds */ - lp_var_t time = lp_var_t(sid.objectId, - PoolIds::TIME_VERSION_SET, this); - lp_var_t program = lp_var_t(sid.objectId, - PoolIds::PROGRAM, this); - lp_var_t major = lp_var_t(sid.objectId, - PoolIds::MAJOR, this); - lp_var_t minor = lp_var_t(sid.objectId, - PoolIds::MINOR, this); - - void printSet() { - PoolReadGuard rg(this); - sif::info << "VersionSet::printSet: Ticks: " - << this->ticks << std::endl; - sif::info << "VersionSet::printSet: Unix Time: " - << this->time << " us" << std::endl; - sif::info << "VersionSet::printSet: Program: " - << static_cast(this->program.value) << std::endl; - sif::info << "VersionSet::printSet: Major: " - << static_cast(this->major.value) << std::endl; - sif::info << "VersionSet::printSet: Minor: " - << static_cast(this->minor.value) << std::endl; - } -}; - -/** - * @brief Dataset to store the interface telemtry data. - */ -class InterfaceSet: - public StaticLocalDataSet { -public: - - static const size_t SIZE = 20; - - InterfaceSet(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, REQ_INTERFACE) { - } - - InterfaceSet(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, REQ_INTERFACE)) { - } - - // Ticks is time reference generated by interanl counter of the star tracker - lp_var_t ticks = lp_var_t(sid.objectId, - PoolIds::TICKS_INTERFACE_SET, this); - /** Unix time in microseconds */ - lp_var_t time = lp_var_t(sid.objectId, - PoolIds::TIME_INTERFACE_SET, this); - lp_var_t frameCount = lp_var_t(sid.objectId, - PoolIds::FRAME_COUNT, this); - lp_var_t checksumerrorCount = lp_var_t(sid.objectId, - PoolIds::CHECKSUM_ERROR_COUNT, this); - - void printSet() { - PoolReadGuard rg(this); - sif::info << "InterfaceSet::printSet: Ticks: " - << this->ticks << std::endl; - sif::info << "InterfaceSet::printSet: Time: " - << this->time << " us" << std::endl; - sif::info << "InterfaceSet::printSet: Frame Count: " - << this->frameCount << std::endl; - sif::info << "InterfaceSet::printSet: Checksum Error Count: " - << this->checksumerrorCount << std::endl; - } -}; - -/** - * @brief Dataset to store the data of the power telemetry reply. - */ -class PowerSet: - public StaticLocalDataSet { -public: - - static const size_t SIZE = 76; - - PowerSet(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, REQ_INTERFACE) { - } - - PowerSet(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, REQ_INTERFACE)) { - } - - // Ticks is time reference generated by interanl counter of the star tracker - lp_var_t ticks = lp_var_t(sid.objectId, - PoolIds::TICKS_POWER_SET, this); - /** Unix time in microseconds */ - lp_var_t time = lp_var_t(sid.objectId, - PoolIds::TIME_POWER_SET, this); - lp_var_t mcuCurrent = lp_var_t(sid.objectId, - PoolIds::MCU_CURRENT, this); - lp_var_t mcuVoltage = lp_var_t(sid.objectId, - PoolIds::MCU_VOLTAGE, this); - lp_var_t fpgaCoreCurrent = lp_var_t(sid.objectId, - PoolIds::FPGA_CORE_CURRENT, this); - lp_var_t fpgaCoreVoltage = lp_var_t(sid.objectId, - PoolIds::FPGA_CORE_VOLTAGE, this); - lp_var_t fpga18Current = lp_var_t(sid.objectId, - PoolIds::FPGA_18_CURRENT, this); - lp_var_t fpga18Voltage = lp_var_t(sid.objectId, - PoolIds::FPGA_18_VOLTAGE, this); - lp_var_t fpga25Current = lp_var_t(sid.objectId, - PoolIds::FPGA_25_CURRENT, this); - lp_var_t fpga25Voltage = lp_var_t(sid.objectId, - PoolIds::FPGA_25_VOLTAGE, this); - lp_var_t cmv21Current = lp_var_t(sid.objectId, - PoolIds::CMV_21_CURRENT, this); - lp_var_t cmv21Voltage = lp_var_t(sid.objectId, - PoolIds::CMV_21_VOLTAGE, this); - lp_var_t cmvPixCurrent = lp_var_t(sid.objectId, - PoolIds::CMV_PIX_CURRENT, this); - lp_var_t cmvPixVoltage = lp_var_t(sid.objectId, - PoolIds::CMV_PIX_VOLTAGE, this); - lp_var_t cmv33Current = lp_var_t(sid.objectId, - PoolIds::CMV_33_CURRENT, this); - lp_var_t cmv33Voltage = lp_var_t(sid.objectId, - PoolIds::CMV_33_VOLTAGE, this); - lp_var_t cmvResCurrent = lp_var_t(sid.objectId, - PoolIds::CMV_RES_CURRENT, this); - lp_var_t cmvResVoltage = lp_var_t(sid.objectId, - PoolIds::CMV_RES_VOLTAGE, this); - - void printSet() { - PoolReadGuard rg(this); - sif::info << "PowerSet::printSet: Ticks: " - << this->ticks << std::endl; - sif::info << "PowerSet::printSet: Time: " - << this->time << " us" << std::endl; - sif::info << "PowerSet::printSet: MCU Current: " - << this->mcuCurrent << " A" << std::endl; - sif::info << "PowerSet::printSet: MCU Voltage: " - << this->mcuVoltage << " V" << std::endl; - sif::info << "PowerSet::printSet: FPGA Core current: " - << this->fpgaCoreCurrent << " A" << std::endl; - sif::info << "PowerSet::printSet: FPGA Core voltage: " - << this->fpgaCoreVoltage << " V" << std::endl; - sif::info << "PowerSet::printSet: FPGA 18 current: " - << this->fpga18Current << " A" << std::endl; - sif::info << "PowerSet::printSet: FPGA 18 voltage: " - << this->fpga18Voltage << " V" << std::endl; - sif::info << "PowerSet::printSet: FPGA 25 current: " - << this->fpga25Current << " A" << std::endl; - sif::info << "PowerSet::printSet: FPGA 25 voltage: " - << this->fpga25Voltage << " V" << std::endl; - sif::info << "PowerSet::printSet: CMV 21 current: " - << this->cmv21Current << " A" << std::endl; - sif::info << "PowerSet::printSet: CMV 21 voltage: " - << this->cmv21Voltage << " V" << std::endl; - sif::info << "PowerSet::printSet: CMV Pix current: " - << this->cmvPixCurrent << " A" << std::endl; - sif::info << "PowerSet::printSet: CMV Pix voltage: " - << this->cmvPixVoltage << " V" << std::endl; - sif::info << "PowerSet::printSet: CMV 33 current: " - << this->cmv33Current << " A" << std::endl; - sif::info << "PowerSet::printSet: CMV 33 voltage: " - << this->cmv33Voltage << " V" << std::endl; - sif::info << "PowerSet::printSet: CMV Res current: " - << this->cmvResCurrent << " A" << std::endl; - sif::info << "PowerSet::printSet: CMV Res voltage: " - << this->cmvResVoltage << " V" << std::endl; - } -}; - -/** - * @brief Data set to store the time telemetry packet. - */ -class TimeSet: - public StaticLocalDataSet { -public: - - static const size_t SIZE = 24; - - TimeSet(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, TIME_SET_ID) { - } - - TimeSet(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, TIME_SET_ID)) { - } - - lp_var_t ticks = lp_var_t(sid.objectId, - PoolIds::TICKS_TIME_SET, this); - /** Unix time in microseconds */ - lp_var_t time = lp_var_t(sid.objectId, - PoolIds::TIME_TIME_SET, this); - // Number of milliseconds since processor start-up - lp_var_t runTime = lp_var_t(sid.objectId, - PoolIds::RUN_TIME, this); - // Unix time in seconds?? --> maybe typo in datasheet. Seems to be microseconds - lp_var_t unixTime = lp_var_t(sid.objectId, - PoolIds::UNIX_TIME, this); - void printSet() { - PoolReadGuard rg(this); - sif::info << "TimeSet::printSet: Ticks: " - << this->ticks << std::endl; - sif::info << "TimeSet::printSet: Time (time stamp): " - << this->time << " us" << std::endl; - sif::info << "TimeSet::printSet: Run Time: " - << this->runTime << " ms" << std::endl; - sif::info << "TimeSet::printSet: Unix Time: " - << this->unixTime << " s" << std::endl; - } -}; - -/** - * @brief The solution dataset is the main dataset of the star tracker and contains the - * attitude information. - */ -class SolutionSet: - public StaticLocalDataSet { -public: - - static const size_t SIZE = 78; - - SolutionSet(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, SOLUTION_SET_ID) { - } - - SolutionSet(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, SOLUTION_SET_ID)) { - } - - // Ticks timestamp - lp_var_t ticks = lp_var_t(sid.objectId, - PoolIds::TICKS_SOLUTION_SET, this); - /// Unix time stamp - lp_var_t time = lp_var_t(sid.objectId, - PoolIds::TIME_SOLUTION_SET, this); - // Calibrated quaternion (takes into account the mounting quaternion), typically same as - // track q values - lp_var_t caliQw = lp_var_t(sid.objectId, PoolIds::CALI_QW, this); - lp_var_t caliQx = lp_var_t(sid.objectId, PoolIds::CALI_QX, this); - lp_var_t caliQy = lp_var_t(sid.objectId, PoolIds::CALI_QY, this); - lp_var_t caliQz = lp_var_t(sid.objectId, PoolIds::CALI_QZ, this); - // The lower this value the more confidence that the star tracker solution is correct - lp_var_t trackConfidence = lp_var_t(sid.objectId, PoolIds::TRACK_CONFIDENCE, - this); - // Estimated attitude of spacecraft - lp_var_t trackQw = lp_var_t(sid.objectId, PoolIds::TRACK_QW, this); - lp_var_t trackQx = lp_var_t(sid.objectId, PoolIds::TRACK_QX, this); - lp_var_t trackQy = lp_var_t(sid.objectId, PoolIds::TRACK_QY, this); - lp_var_t trackQz = lp_var_t(sid.objectId, PoolIds::TRACK_QZ, this); - // Number of stars removed from tracking solution - lp_var_t trackRemoved = lp_var_t(sid.objectId, PoolIds::TRACK_REMOVED, this); - // Number of stars for which a valid centroid was found - lp_var_t starsCentroided = lp_var_t(sid.objectId, PoolIds::STARS_CENTROIDED, - this); - // Number of stars that matched to a database star - lp_var_t starsMatchedDatabase = lp_var_t(sid.objectId, - PoolIds::STARS_MATCHED_DATABASE, this); - // Result of LISA (lost in space algorithm), searches for stars without prior knowledge of - // attitude - lp_var_t lisaQw = lp_var_t(sid.objectId, PoolIds::LISA_QW, this); - lp_var_t lisaQx = lp_var_t(sid.objectId, PoolIds::LISA_QX, this); - lp_var_t lisaQy = lp_var_t(sid.objectId, PoolIds::LISA_QY, this); - lp_var_t lisaQz = lp_var_t(sid.objectId, PoolIds::LISA_QZ, this); - // Percentage of close stars in LISA solution - lp_var_t lisaPercentageClose = lp_var_t(sid.objectId, PoolIds::LISA_PERC_CLOSE, - this); - // Number of close stars in LISA solution - lp_var_t lisaNrClose = lp_var_t(sid.objectId, PoolIds::LISA_NR_CLOSE, this); - // Gives a combined overview of the validation parameters (1 for valid solution, otherwise 0) - lp_var_t isTrustWorthy = lp_var_t(sid.objectId, PoolIds::TRUST_WORTHY, this); - // Number of times the validation criteria was met - lp_var_t stableCount = lp_var_t(sid.objectId, PoolIds::STABLE_COUNT, this); - // Shows the autonomous mode used to obtain the star tracker attitude - lp_var_t solutionStrategy = lp_var_t(sid.objectId, PoolIds::SOLUTION_STRATEGY, - this); - - void printSet() { - PoolReadGuard rg(this); - sif::info << "SolutionSet::printSet: Ticks: " - << this->ticks << std::endl; - sif::info << "SolutionSet::printSet: Time: " - << this->time << std::endl; - sif::info << "SolutionSet::printSet: Calibrated quaternion Qw: " - << this->caliQw << std::endl; - sif::info << "SolutionSet::printSet: Calibrated quaternion Qx: " - << this->caliQx << std::endl; - sif::info << "SolutionSet::printSet: Calibrated quaternion Qy: " - << this->caliQy << std::endl; - sif::info << "SolutionSet::printSet: Calibrated quaternion Qz: " - << this->caliQz << std::endl; - sif::info << "SolutionSet::printSet: Track confidence: " - << this->trackConfidence << std::endl; - sif::info << "SolutionSet::printSet: Track Qw: " - << this->trackQw << std::endl; - sif::info << "SolutionSet::printSet: Track Qx: " - << this->trackQx << std::endl; - sif::info << "SolutionSet::printSet: Track Qy: " - << this->trackQy << std::endl; - sif::info << "SolutionSet::printSet: Track Qz: " - << this->trackQz << std::endl; - sif::info << "SolutionSet::printSet: Track removed: " - << static_cast(this->trackRemoved.value) << std::endl; - sif::info << "SolutionSet::printSet: Number of stars centroided: " - << static_cast(this->starsCentroided.value) << std::endl; - sif::info << "SolutionSet::printSet: Number of stars matched database: " - << static_cast(this->starsMatchedDatabase.value) << std::endl; - sif::info << "SolutionSet::printSet: LISA Qw: " - << this->lisaQw << std::endl; - sif::info << "SolutionSet::printSet: LISA Qx: " - << this->lisaQx << std::endl; - sif::info << "SolutionSet::printSet: LISA Qy: " - << this->lisaQy << std::endl; - sif::info << "SolutionSet::printSet: LISA Qz: " - << this->lisaQz << std::endl; - sif::info << "SolutionSet::printSet: LISA Percentage close: " - << this->lisaPercentageClose << std::endl; - sif::info << "SolutionSet::printSet: LISA number of close stars: " - << static_cast(this->lisaNrClose.value) << std::endl; - sif::info << "SolutionSet::printSet: Is trust worthy: " - << static_cast(this->isTrustWorthy.value) << std::endl; - sif::info << "SolutionSet::printSet: Stable count: " - << this->stableCount << std::endl; - sif::info << "SolutionSet::printSet: Solution strategy: " - << static_cast(this->solutionStrategy.value) << std::endl; - } -}; - -/** - * @brief Dataset to store the histogram - */ -class HistogramSet: - public StaticLocalDataSet { -public: - - // Size of dataset - static const size_t SIZE = 156; - - HistogramSet(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, HISTOGRAM_SET_ID) { - } - - HistogramSet(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, HISTOGRAM_SET_ID)) { - } - - lp_var_t ticks = lp_var_t(sid.objectId, PoolIds::TICKS_HISTOGRAM_SET, this); - lp_var_t time = lp_var_t(sid.objectId, PoolIds::TIME_HISTOGRAM_SET, this); - lp_var_t binA0 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA0, this); - lp_var_t binA1 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA1, this); - lp_var_t binA2 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA2, this); - lp_var_t binA3 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA3, this); - lp_var_t binA4 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA4, this); - lp_var_t binA5 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA5, this); - lp_var_t binA6 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA6, this); - lp_var_t binA7 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA7, this); - lp_var_t binA8 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA8, this); - lp_var_t binB0 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB0, this); - lp_var_t binB1 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB1, this); - lp_var_t binB2 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB2, this); - lp_var_t binB3 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB3, this); - lp_var_t binB4 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB4, this); - lp_var_t binB5 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB5, this); - lp_var_t binB6 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB6, this); - lp_var_t binB7 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB7, this); - lp_var_t binB8 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB8, this); - lp_var_t binC0 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC0, this); - lp_var_t binC1 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC1, this); - lp_var_t binC2 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC2, this); - lp_var_t binC3 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC3, this); - lp_var_t binC4 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC4, this); - lp_var_t binC5 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC5, this); - lp_var_t binC6 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC6, this); - lp_var_t binC7 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC7, this); - lp_var_t binC8 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC8, this); - lp_var_t binD0 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND0, this); - lp_var_t binD1 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND1, this); - lp_var_t binD2 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND2, this); - lp_var_t binD3 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND3, this); - lp_var_t binD4 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND4, this); - lp_var_t binD5 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND5, this); - lp_var_t binD6 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND6, this); - lp_var_t binD7 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND7, this); - lp_var_t binD8 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND8, this); - - void printSet() { - PoolReadGuard rg(this); - sif::info << "HistogramSet::printSet: Ticks: " << this->ticks << std::endl; - sif::info << "HistogramSet::printSet: Time (time stamp): " << this->time << " us" - << std::endl; - sif::info << "HistogramSet::printSet: BinA0: " << this->binA0 << std::endl; - sif::info << "HistogramSet::printSet: BinA1: " << this->binA1 << std::endl; - sif::info << "HistogramSet::printSet: BinA2: " << this->binA2 << std::endl; - sif::info << "HistogramSet::printSet: BinA3: " << this->binA3 << std::endl; - sif::info << "HistogramSet::printSet: BinA4: " << this->binA4 << std::endl; - sif::info << "HistogramSet::printSet: BinA5: " << this->binA5 << std::endl; - sif::info << "HistogramSet::printSet: BinA6: " << this->binA6 << std::endl; - sif::info << "HistogramSet::printSet: BinA7: " << this->binA7 << std::endl; - sif::info << "HistogramSet::printSet: BinA8: " << this->binA8 << std::endl; - sif::info << "HistogramSet::printSet: BinB0: " << this->binB0 << std::endl; - sif::info << "HistogramSet::printSet: BinB1: " << this->binB1 << std::endl; - sif::info << "HistogramSet::printSet: BinB2: " << this->binB2 << std::endl; - sif::info << "HistogramSet::printSet: BinB3: " << this->binB3 << std::endl; - sif::info << "HistogramSet::printSet: BinB4: " << this->binB4 << std::endl; - sif::info << "HistogramSet::printSet: BinB5: " << this->binB5 << std::endl; - sif::info << "HistogramSet::printSet: BinB6: " << this->binB6 << std::endl; - sif::info << "HistogramSet::printSet: BinB7: " << this->binB7 << std::endl; - sif::info << "HistogramSet::printSet: BinB8: " << this->binB8 << std::endl; - sif::info << "HistogramSet::printSet: BinC0: " << this->binC0 << std::endl; - sif::info << "HistogramSet::printSet: BinC1: " << this->binC1 << std::endl; - sif::info << "HistogramSet::printSet: BinC2: " << this->binC2 << std::endl; - sif::info << "HistogramSet::printSet: BinC3: " << this->binC3 << std::endl; - sif::info << "HistogramSet::printSet: BinC4: " << this->binC4 << std::endl; - sif::info << "HistogramSet::printSet: BinC5: " << this->binC5 << std::endl; - sif::info << "HistogramSet::printSet: BinC6: " << this->binC6 << std::endl; - sif::info << "HistogramSet::printSet: BinC7: " << this->binC7 << std::endl; - sif::info << "HistogramSet::printSet: BinC8: " << this->binC8 << std::endl; - sif::info << "HistogramSet::printSet: BinD0: " << this->binD0 << std::endl; - sif::info << "HistogramSet::printSet: BinD1: " << this->binD1 << std::endl; - sif::info << "HistogramSet::printSet: BinD2: " << this->binD2 << std::endl; - sif::info << "HistogramSet::printSet: BinD3: " << this->binD3 << std::endl; - sif::info << "HistogramSet::printSet: BinD4: " << this->binD4 << std::endl; - sif::info << "HistogramSet::printSet: BinD5: " << this->binD5 << std::endl; - sif::info << "HistogramSet::printSet: BinD6: " << this->binD6 << std::endl; - sif::info << "HistogramSet::printSet: BinD7: " << this->binD7 << std::endl; - sif::info << "HistogramSet::printSet: BinD8: " << this->binD8 << std::endl; - } -}; - -/** - * @brief Dataset to store the contrast telemetry data - */ -class ContrastSet: - public StaticLocalDataSet { -public: - - // Size of dataset - static const size_t SIZE = 156; - - ContrastSet(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, CONTRAST_SET_ID) { - } - - ContrastSet(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, CONTRAST_SET_ID)) { - } - - lp_var_t ticks = lp_var_t(sid.objectId, PoolIds::TICKS_CONTRAST_SET, this); - lp_var_t time = lp_var_t(sid.objectId, PoolIds::TIME_CONTRAST_SET, this); - lp_var_t binA0 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA0, this); - lp_var_t binA1 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA1, this); - lp_var_t binA2 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA2, this); - lp_var_t binA3 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA3, this); - lp_var_t binA4 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA4, this); - lp_var_t binA5 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA5, this); - lp_var_t binA6 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA6, this); - lp_var_t binA7 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA7, this); - lp_var_t binA8 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA8, this); - lp_var_t binb0 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB0, this); - lp_var_t binB1 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB1, this); - lp_var_t binB2 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB2, this); - lp_var_t binB3 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB3, this); - lp_var_t binB4 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB4, this); - lp_var_t binB5 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB5, this); - lp_var_t binB6 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB6, this); - lp_var_t binB7 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB7, this); - lp_var_t binB8 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB8, this); - lp_var_t binC0 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC0, this); - lp_var_t binC1 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC1, this); - lp_var_t binC2 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC2, this); - lp_var_t binC3 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC3, this); - lp_var_t binC4 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC4, this); - lp_var_t binC5 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC5, this); - lp_var_t binC6 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC6, this); - lp_var_t binC7 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC7, this); - lp_var_t binC8 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC8, this); - lp_var_t binD0 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND0, this); - lp_var_t binD1 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND1, this); - lp_var_t binD2 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND2, this); - lp_var_t binD3 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND3, this); - lp_var_t binD4 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND4, this); - lp_var_t binD5 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND5, this); - lp_var_t binD6 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND6, this); - lp_var_t binD7 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND7, this); - lp_var_t binD8 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND8, this); - - void printSet() { - PoolReadGuard rg(this); - sif::info << "ContrastSet::printSet: Ticks: " << this->ticks << std::endl; - sif::info << "ContrastSet::printSet: Time (time stamp): " << this->time << " us" - << std::endl; - sif::info << "ContrastSet::printSet: BinA0: " << this->binA0 << std::endl; - sif::info << "ContrastSet::printSet: BinA1: " << this->binA1 << std::endl; - sif::info << "ContrastSet::printSet: BinA2: " << this->binA2 << std::endl; - sif::info << "ContrastSet::printSet: BinA3: " << this->binA3 << std::endl; - sif::info << "ContrastSet::printSet: BinA4: " << this->binA4 << std::endl; - sif::info << "ContrastSet::printSet: BinA5: " << this->binA5 << std::endl; - sif::info << "ContrastSet::printSet: BinA6: " << this->binA6 << std::endl; - sif::info << "ContrastSet::printSet: BinA7: " << this->binA7 << std::endl; - sif::info << "ContrastSet::printSet: BinA8: " << this->binA8 << std::endl; - sif::info << "ContrastSet::printSet: BinB0: " << this->binA0 << std::endl; - sif::info << "ContrastSet::printSet: BinB1: " << this->binB1 << std::endl; - sif::info << "ContrastSet::printSet: BinB2: " << this->binB2 << std::endl; - sif::info << "ContrastSet::printSet: BinB3: " << this->binB3 << std::endl; - sif::info << "ContrastSet::printSet: BinB4: " << this->binB4 << std::endl; - sif::info << "ContrastSet::printSet: BinB5: " << this->binB5 << std::endl; - sif::info << "ContrastSet::printSet: BinB6: " << this->binB6 << std::endl; - sif::info << "ContrastSet::printSet: BinB7: " << this->binB7 << std::endl; - sif::info << "ContrastSet::printSet: BinB8: " << this->binB8 << std::endl; - sif::info << "ContrastSet::printSet: BinC0: " << this->binC0 << std::endl; - sif::info << "ContrastSet::printSet: BinC1: " << this->binC1 << std::endl; - sif::info << "ContrastSet::printSet: BinC2: " << this->binC2 << std::endl; - sif::info << "ContrastSet::printSet: BinC3: " << this->binC3 << std::endl; - sif::info << "ContrastSet::printSet: BinC4: " << this->binC4 << std::endl; - sif::info << "ContrastSet::printSet: BinC5: " << this->binC5 << std::endl; - sif::info << "ContrastSet::printSet: BinC6: " << this->binC6 << std::endl; - sif::info << "ContrastSet::printSet: BinC7: " << this->binC7 << std::endl; - sif::info << "ContrastSet::printSet: BinC8: " << this->binC8 << std::endl; - sif::info << "ContrastSet::printSet: BinD0: " << this->binD0 << std::endl; - sif::info << "ContrastSet::printSet: BinD1: " << this->binD1 << std::endl; - sif::info << "ContrastSet::printSet: BinD2: " << this->binD2 << std::endl; - sif::info << "ContrastSet::printSet: BinD3: " << this->binD3 << std::endl; - sif::info << "ContrastSet::printSet: BinD4: " << this->binD4 << std::endl; - sif::info << "ContrastSet::printSet: BinD5: " << this->binD5 << std::endl; - sif::info << "ContrastSet::printSet: BinD6: " << this->binD6 << std::endl; - sif::info << "ContrastSet::printSet: BinD7: " << this->binD7 << std::endl; - sif::info << "ContrastSet::printSet: BinD8: " << this->binD8 << std::endl; - } -}; - -/** - * @brief Helper Class to extract information from bytestream. - */ -class ChecksumReply { -public: - - /** - * @brief Constructor - * - * @param datafield Pointer to datafield in reply buffer - * - */ - ChecksumReply(const uint8_t* datafield) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - region = *(datafield); - const uint8_t* addressData = datafield + ADDRESS_OFFSET; - size_t size = sizeof(address); - result = SerializeAdapter::deSerialize(&address, &addressData, &size, - SerializeIF::Endianness::LITTLE); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::debug << "ChecksumReply::ChecksumReply: Failed to deserialize address" - << std::endl; - } - const uint8_t* lengthData = datafield + LENGTH_OFFSET; - size = sizeof(length); - result = SerializeAdapter::deSerialize(&length, &lengthData, &size, - SerializeIF::Endianness::LITTLE); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::debug << "ChecksumReply::ChecksumReply: Failed to deserialize length" - << std::endl; - } - const uint8_t* checksumData = datafield + CHECKSUM_OFFSET; - size = sizeof(checksum); - result = SerializeAdapter::deSerialize(&checksum, &checksumData, &size, - SerializeIF::Endianness::LITTLE); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::debug << "ChecksumReply::ChecksumReply: Failed to deserialize checksum" - << std::endl; - } - } - - uint8_t getRegion() { - return region; - } - - uint32_t getAddress() { - return address; - } - - uint32_t getLength() { - return length; - } - - uint32_t getChecksum() { - return checksum; - } - - void printChecksum() { - sif::info << "ChecksumReply::printChecksum: 0x" << std::hex << checksum << std::endl; - } - -private: - - static const uint8_t ADDRESS_OFFSET = 1; - static const uint8_t LENGTH_OFFSET = 5; - static const uint8_t CHECKSUM_OFFSET = 9; - - uint8_t region = 0; - uint32_t address = 0; - uint32_t length = 0; - uint32_t checksum = 0; -}; - -class EraseReply { -public: - EraseReply(const uint8_t* datafield) { - region = *datafield; - } - - uint8_t getRegion() { - return region; - } - -private: - uint8_t region = 0; -}; - -class ChecksumSet: - public StaticLocalDataSet { -public: - - // Size of dataset - static const size_t SIZE = 156; - - ChecksumSet(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, CHECKSUM_SET_ID) { - } - - ChecksumSet(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, CHECKSUM_SET_ID)) { - } - - lp_var_t checksum = lp_var_t(sid.objectId, PoolIds::CHKSUM, this); -}; - -/** - * @brief Dataset to store download centroid response - */ -class DownloadCentroidSet: - public StaticLocalDataSet { -public: - - // Size of dataset - static const size_t SIZE = 34; - - DownloadCentroidSet(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, DOWNLOADCENTROID_SET_ID) { - } - - DownloadCentroidSet(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, DOWNLOADCENTROID_SET_ID)) { - } - - lp_var_t id = lp_var_t(sid.objectId, PoolIds::DWL_ID, this); - lp_var_t pixx = lp_var_t(sid.objectId, PoolIds::DWL_PIXX, this); - lp_var_t pixy = lp_var_t(sid.objectId, PoolIds::DWL_PIXY, this); - lp_var_t xUncorrected = lp_var_t(sid.objectId, PoolIds::DWL_X_UNCORRECTED, this); - lp_var_t yUncorrected = lp_var_t(sid.objectId, PoolIds::DWL_Y_UNCORRECTED, this); - lp_var_t xCorrected = lp_var_t(sid.objectId, PoolIds::DWL_X_CORRECTED, this); - lp_var_t yCorrected = lp_var_t(sid.objectId, PoolIds::DWL_Y_CORRECTED, this); - lp_var_t magnitude = lp_var_t(sid.objectId, PoolIds::DWL_MAGNITUDE, this); - lp_var_t cxa = lp_var_t(sid.objectId, PoolIds::DWL_CXA, this); - lp_var_t cya = lp_var_t(sid.objectId, PoolIds::DWL_CYA, this); - lp_var_t quality = lp_var_t(sid.objectId, PoolIds::DWL_QUALITY, this); - - void printSet() { - PoolReadGuard rg(this); - sif::info << "ContrastSet::printSet: id: " << static_cast(this->id.value) - << std::endl; - sif::info << "ContrastSet::printSet: pixx: " << this->pixx << std::endl; - sif::info << "ContrastSet::printSet: pixy: " << this->pixy << std::endl; - sif::info << "ContrastSet::printSet: xUncorrected: " << this->xUncorrected << std::endl; - sif::info << "ContrastSet::printSet: yUncorrected: " << this->yUncorrected << std::endl; - sif::info << "ContrastSet::printSet: xCorrected: " << this->xCorrected << std::endl; - sif::info << "ContrastSet::printSet: yCorrected: " << this->yCorrected << std::endl; - sif::info << "ContrastSet::printSet: magnitude: " << this->magnitude << std::endl; - sif::info << "ContrastSet::printSet: cxa: " << this->cxa << std::endl; - sif::info << "ContrastSet::printSet: cya: " << this->cya << std::endl; - sif::info << "ContrastSet::printSet: quality: " << this->quality << std::endl; - } -}; - -namespace UploadCentroidKeys { - static const char id[] = "id"; - static const char pixx[] = "pixx"; - static const char pixy[] = "pixy"; - static const char x_uncorrected[] = "x_uncorrected"; - static const char y_uncorrected[] = "y_uncorrected"; - static const char x_corrected[] = "x_corrected"; - static const char y_corrected[] = "y_corrected"; - static const char magnitude[] = "magnitude"; - static const char cxa[] = "cxa"; - static const char cya[] = "cya"; - static const char quality[] = "quality"; -}; - -/** - * @brief Dataset to store matched star information - */ -class DownloadMatchedStar : - public StaticLocalDataSet { -public: - - // Size of dataset - static const size_t SIZE = 53; - - DownloadMatchedStar(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, DOWNLOAD_MATCHED_STAR_SET_ID) { - } - - DownloadMatchedStar(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, DOWNLOAD_MATCHED_STAR_SET_ID)) { - } - - lp_var_t id = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_ID, this); - lp_var_t camfpx = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMFPX, this); - lp_var_t camfpy = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMFPY, this); - lp_var_t camcartx = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMCARTX, this); - lp_var_t camcarty = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMCARTY, this); - lp_var_t camcartz = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMCARTZ, this); - lp_var_t cammagnitude = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMMAGNITUDE, - this); - lp_var_t dbfpx = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBFPX, this); - lp_var_t dbfpy = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBFPY, this); - lp_var_t dbcartx = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBCARTX, this); - lp_var_t dbcarty = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBCARTY, this); - lp_var_t dbcartz = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBCARTZ, this); - lp_var_t dbmagnitude = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBMAGNITUDE, - this); - lp_var_t catalogid = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CATALOGID, - this); - - void printSet() { - PoolReadGuard rg(this); - sif::info << "DownloadMatchedStar::printSet: id: " - << static_cast(this->id.value) << std::endl; - sif::info << "DownloadMatchedStar::printSet: camfpx: " << this->camfpx << std::endl; - sif::info << "DownloadMatchedStar::printSet: camfpy: " << this->camfpy << std::endl; - sif::info << "DownloadMatchedStar::printSet: camcartx: " << this->camcartx << std::endl; - sif::info << "DownloadMatchedStar::printSet: camcarty: " << this->camcarty << std::endl; - sif::info << "DownloadMatchedStar::printSet: camcartz: " << this->camcartz << std::endl; - sif::info << "DownloadMatchedStar::printSet: cammagnitude: " << this->cammagnitude - << std::endl; - sif::info << "DownloadMatchedStar::printSet: dbfpx: " << this->dbfpx << std::endl; - sif::info << "DownloadMatchedStar::printSet: dbfpy: " << this->dbfpy << std::endl; - sif::info << "DownloadMatchedStar::printSet: dbcartx: " << this->dbcartx << std::endl; - sif::info << "DownloadMatchedStar::printSet: dbcarty: " << this->dbcarty << std::endl; - sif::info << "DownloadMatchedStar::printSet: dbcartz: " << this->dbcartz << std::endl; - sif::info << "DownloadMatchedStar::printSet: dbmagnitude: " << this->dbmagnitude - << std::endl; - sif::info << "DownloadMatchedStar::printSet: catalogid: " << this->catalogid << std::endl; - } -}; - -/** - * @brief Dataset to store the response to the DownloadDBImage request - */ -class DownloadDBImage : - public StaticLocalDataSet { -public: - - // Size of dataset - static const size_t SIZE = 21; - - DownloadDBImage(HasLocalDataPoolIF* owner): - StaticLocalDataSet(owner, DOWNLOAD_DBIMAGE_SET_ID) { - } - - DownloadDBImage(object_id_t objectId): - StaticLocalDataSet(sid_t(objectId, DOWNLOAD_DBIMAGE_SET_ID)) { - } - - lp_var_t id = lp_var_t(sid.objectId, PoolIds::DBIMAGE_ID, this); - lp_var_t pixx = lp_var_t(sid.objectId, PoolIds::DBIMAGE_PIXX, this); - lp_var_t pixy = lp_var_t(sid.objectId, PoolIds::DBIMAGE_PIXY, this); - lp_var_t x = lp_var_t(sid.objectId, PoolIds::DBIMAGE_X, this); - lp_var_t y = lp_var_t(sid.objectId, PoolIds::DBIMAGE_Y, this); - lp_var_t magnitude = lp_var_t(sid.objectId, PoolIds::DBIMAGE_MAGNITUDE, this); - - void printSet() { - PoolReadGuard rg(this); - sif::info << "DownloadDBImage::printSet: id: " - << static_cast(this->id.value) << std::endl; - sif::info << "DownloadDBImage::printSet: pixx: " << this->pixx << std::endl; - sif::info << "DownloadDBImage::printSet: pixy: " << this->pixy << std::endl; - sif::info << "DownloadDBImage::printSet: x: " << this->x << std::endl; - sif::info << "DownloadDBImage::printSet: y: " << this->y << std::endl; - sif::info << "DownloadDBImage::printSet: magnitude: " << this->magnitude << std::endl; - } -}; - -/** - * @brief Dataset to store the response to the download blob pixel action request - */ -class DownloadBlobPixel: public StaticLocalDataSet { -public: - - // Size of dataset - static const size_t SIZE = 22; - - DownloadBlobPixel(HasLocalDataPoolIF* owner) : - StaticLocalDataSet(owner, DOWNLOAD_BLOBPIXEL_SET_ID) { - } - - DownloadBlobPixel(object_id_t objectId) : - StaticLocalDataSet(sid_t(objectId, DOWNLOAD_BLOBPIXEL_SET_ENTRIES)) { - } - - lp_var_t id = lp_var_t(sid.objectId, PoolIds::BLOBPIX_ID, this); - lp_var_t x = lp_var_t(sid.objectId, PoolIds::BLOBPIX_X, this); - lp_var_t y = lp_var_t(sid.objectId, PoolIds::BLOBPIX_Y, this); - lp_var_t totalValue = lp_var_t(sid.objectId, PoolIds::BLOBPIX_TOT_VAL, this); - lp_var_t inUse = lp_var_t(sid.objectId, PoolIds::BLOBPIX_IN_USE, this); - lp_var_t brightNeighbours = lp_var_t(sid.objectId, - PoolIds::BLOBPIX_BRIGHT_NEIGHBOURS, this); - lp_var_t region = lp_var_t(sid.objectId, PoolIds::BLOBPIX_REGION, this); - - void printSet() { - PoolReadGuard rg(this); - sif::info << "DownloadBlobPixel::printSet: id: " - << static_cast(this->id.value) << std::endl; - sif::info << "DownloadBlobPixel::printSet: x: " << this->x << std::endl; - sif::info << "DownloadBlobPixel::printSet: y: " << this->y << std::endl; - sif::info << "DownloadBlobPixel::printSet: totalValue: " << this->totalValue << std::endl; - sif::info << "DownloadBlobPixel::printSet: inUse: " - << static_cast(this->inUse.value) << std::endl; - sif::info << "DownloadBlobPixel::printSet: brightNeighbours: " << this->brightNeighbours - << std::endl; - sif::info << "DownloadBlobPixel::printSet: region: " << this->region << std::endl; - } -}; -} -#endif /* MISSION_STARTRACKER_DEFINITIONS_H_ */ diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp deleted file mode 100644 index de70037a..00000000 --- a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp +++ /dev/null @@ -1,1949 +0,0 @@ -#include -#include "StarTrackerHandler.h" -#include "OBSWConfig.h" -#include "StarTrackerJsonCommands.h" -#include -#include -#include -extern "C" { - #include - #include - #include "common/misc.h" -} - -using json = nlohmann::json; - -StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, - CookieIF * comCookie, StrHelper* strHelper) : - DeviceHandlerBase(objectId, comIF, comCookie), temperatureSet(this), versionSet(this), powerSet( - this), interfaceSet(this), timeSet(this), solutionSet(this), histogramSet(this), contrastSet( - this), checksumSet(this), downloadCentroidSet(this), downloadMatchedStar(this), - downloadDbImage(this), downloadBlobPixel(this), strHelper( - strHelper) { - if (comCookie == nullptr) { - sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl; - } - if (strHelper == nullptr) { - sif::error << "StarTrackerHandler: Invalid str image loader" << std::endl; - } - eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5); -} - -StarTrackerHandler::~StarTrackerHandler() { -} - -ReturnValue_t StarTrackerHandler::initialize() { - ReturnValue_t result = RETURN_OK; - result = DeviceHandlerBase::initialize(); - if (result != RETURN_OK) { - return result; - } - - EventManagerIF* manager = ObjectManager::instance()->get( - objects::EVENT_MANAGER); - if (manager == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "StarTrackerHandler::initialize: Invalid event manager" << std::endl; -#endif - return ObjectManagerIF::CHILD_INIT_FAILED;; - } - result = manager->registerListener(eventQueue->getId()); - if (result != RETURN_OK) { - return result; - } - result = manager->subscribeToEventRange(eventQueue->getId(), - event::getEventId(StrHelper::IMAGE_UPLOAD_FAILED), - event::getEventId(StrHelper::FPGA_UPLOAD_FAILED)); - if (result != RETURN_OK) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "StarTrackerHandler::initialize: Failed to subscribe to events from " - " str helper" << std::endl; -#endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } - - result = strHelper->setComIF(communicationInterface); - if (result != RETURN_OK) { - return ObjectManagerIF::CHILD_INIT_FAILED; - } - strHelper->setComCookie(comCookie); - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, - const uint8_t* data, size_t size) { - - ReturnValue_t result = RETURN_OK; - - switch(actionId) { - case(StarTracker::STOP_IMAGE_LOADER): { - strHelper->stopProcess(); - return EXECUTION_FINISHED; - } - case(StarTracker::SET_JSON_FILE_NAME): { - if (size > MAX_PATH_SIZE) { - return FILE_PATH_TOO_LONG; - } - paramJsonFile = std::string(reinterpret_cast(data), size); - return EXECUTION_FINISHED; - } - default: - break; - } - - if (strHelperExecuting == true) { - return IMAGE_LOADER_EXECUTING; - } - - result = checkMode(actionId); - if (result != RETURN_OK) { - return result; - } - - // Intercept image loader commands which do not follow the common DHB communication flow - switch(actionId) { - case(StarTracker::UPLOAD_IMAGE): { - result = DeviceHandlerBase::acceptExternalDeviceCommands(); - if (result != RETURN_OK) { - return result; - } - if (size > MAX_PATH_SIZE + MAX_FILE_NAME) { - return FILE_PATH_TOO_LONG; - } - result = strHelper->startImageUpload( - std::string(reinterpret_cast(data), size)); - if (result != RETURN_OK) { - return result; - } - strHelperExecuting = true; - return EXECUTION_FINISHED; - } - case(StarTracker::DOWNLOAD_IMAGE): { - result = DeviceHandlerBase::acceptExternalDeviceCommands(); - if (result != RETURN_OK) { - return result; - } - if (size > MAX_PATH_SIZE) { - return FILE_PATH_TOO_LONG; - } - result = strHelper->startImageDownload( - std::string(reinterpret_cast(data), size)); - if (result != RETURN_OK) { - return result; - } - strHelperExecuting = true; - return EXECUTION_FINISHED; - } - case(StarTracker::WRITE): { - result = DeviceHandlerBase::acceptExternalDeviceCommands(); - if (result != RETURN_OK) { - return result; - } - result = executeWriteCommand(data, size); - if (result != RETURN_OK) { - return result; - } - - strHelperExecuting = true; - return EXECUTION_FINISHED; - } - case(StarTracker::READ): { - result = DeviceHandlerBase::acceptExternalDeviceCommands(); - if (result != RETURN_OK) { - return result; - } - result = executeReadCommand(data, size); - if (result != RETURN_OK) { - return result; - } - strHelperExecuting = true; - return EXECUTION_FINISHED; - } - case(StarTracker::CHANGE_DOWNLOAD_FILE): { - if (size > MAX_FILE_NAME) { - return FILENAME_TOO_LONG; - } - strHelper->setDownloadImageName( - std::string(reinterpret_cast(data), size)); - return EXECUTION_FINISHED; - } - case(StarTracker::CHANGE_FPGA_DOWNLOAD_FILE): { - if (size > MAX_FILE_NAME) { - return FILENAME_TOO_LONG; - } - strHelper->setDownloadFpgaImage(std::string(reinterpret_cast(data), size)); - return EXECUTION_FINISHED; - } - case(StarTracker::SET_READ_FILENAME): { - if (size > MAX_FILE_NAME) { - return FILENAME_TOO_LONG; - } - strHelper->setDownloadImageName( - std::string(reinterpret_cast(data), size)); - return EXECUTION_FINISHED; - } - case(StarTracker::DOWNLOAD_FPGA_IMAGE): { - result = DeviceHandlerBase::acceptExternalDeviceCommands(); - if (result != RETURN_OK) { - return result; - } - if (size > MAX_PATH_SIZE) { - return FILE_PATH_TOO_LONG; - } - result = executeFpgaDownloadCommand(data, size); - if (result != RETURN_OK) { - return result; - } - strHelperExecuting = true; - return EXECUTION_FINISHED; - } - case(StarTracker::UPLOAD_FPGA_IMAGE): { - result = DeviceHandlerBase::acceptExternalDeviceCommands(); - if (result != RETURN_OK) { - return result; - } - if (size > MAX_PATH_SIZE + MAX_FILE_NAME) { - return FILE_PATH_TOO_LONG; - } - result = strHelper->startFpgaUpload(std::string(reinterpret_cast(data), size)); - if (result != RETURN_OK) { - return result; - } - strHelperExecuting = true; - return EXECUTION_FINISHED; - } - default: - break; - } - return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size); -} - -void StarTrackerHandler::performOperationHook() { - EventMessage event; - for (ReturnValue_t result = eventQueue->receiveMessage(&event); - result == RETURN_OK; result = eventQueue->receiveMessage(&event)) { - switch (event.getMessageId()) { - case EventMessage::EVENT_MESSAGE: - handleEvent(&event); - break; - default: - sif::debug << "CCSDSHandler::checkEvents: Did not subscribe to this event message" - << std::endl; - break; - } - } -} - -void StarTrackerHandler::doStartUp() { - switch(startupState) { - case StartupState::IDLE: - startupState = StartupState::CHECK_BOOT_STATE; - return; - case StartupState::BOOT_DELAY: - if (bootCountdown.hasTimedOut()) { - startupState = StartupState::LIMITS; - } - return; - case StartupState::DONE: - break; - default: - return; - } - setMode(_MODE_TO_ON); -} - -void StarTrackerHandler::doShutDown() { - // If star tracker is shutdown also stop all running processes in the image loader task - strHelper->stopProcess(); - setMode(_MODE_POWER_DOWN); -} - -void StarTrackerHandler::doOffActivity() { - startupState = StartupState::IDLE; -} - -ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t * id) { - switch (internalState) { - case InternalState::TEMPERATURE_REQUEST: - *id = StarTracker::REQ_TEMPERATURE; - break; - default: - sif::debug << "StarTrackerHandler::buildNormalDeviceCommand: Invalid internal step" - << std::endl; - break; - } - return buildCommandFromCommand(*id, NULL, 0); -} - -ReturnValue_t StarTrackerHandler::buildTransitionDeviceCommand(DeviceCommandId_t * id) { - if (mode != _MODE_START_UP) { - return NOTHING_TO_SEND; - } - switch (startupState) { - case StartupState::CHECK_BOOT_STATE: - *id = StarTracker::REQ_VERSION; - startupState = StartupState::WAIT_FOR_EXECUTION; - return buildCommandFromCommand(*id, nullptr, 0); - case StartupState::BOOT: - *id = StarTracker::BOOT; - bootCountdown.setTimeout(BOOT_TIMEOUT); - startupState = StartupState::BOOT_DELAY; - return buildCommandFromCommand(*id, nullptr, 0); - case StartupState::LIMITS: - startupState = StartupState::WAIT_FOR_EXECUTION; - *id = StarTracker::LIMITS; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case StartupState::TRACKING: - startupState = StartupState::WAIT_FOR_EXECUTION; - *id = StarTracker::TRACKING; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case StartupState::MOUNTING: - startupState = StartupState::WAIT_FOR_EXECUTION; - *id = StarTracker::MOUNTING; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case StartupState::CAMERA: - startupState = StartupState::WAIT_FOR_EXECUTION; - *id = StarTracker::CAMERA; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case StartupState::BLOB: - startupState = StartupState::WAIT_FOR_EXECUTION; - *id = StarTracker::BLOB; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case StartupState::CENTROIDING: - startupState = StartupState::WAIT_FOR_EXECUTION; - *id = StarTracker::CENTROIDING; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case StartupState::LISA: - startupState = StartupState::WAIT_FOR_EXECUTION; - *id = StarTracker::LISA; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case StartupState::MATCHING: - startupState = StartupState::WAIT_FOR_EXECUTION; - *id = StarTracker::MATCHING; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case StartupState::VALIDATION: - startupState = StartupState::WAIT_FOR_EXECUTION; - *id = StarTracker::VALIDATION; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case StartupState::ALGO: - startupState = StartupState::WAIT_FOR_EXECUTION; - *id = StarTracker::ALGO; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - default: - break; - } - return NOTHING_TO_SEND; -} - -ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, - const uint8_t * commandData, size_t commandDataLen) { - ReturnValue_t result = RETURN_OK; - switch (deviceCommand) { - case (StarTracker::PING_REQUEST): { - preparePingRequest(); - return RETURN_OK; - } - case (StarTracker::REQ_TIME): { - prepareTimeRequest(); - return RETURN_OK; - } - case (StarTracker::BOOT): { - prepareBootCommand(); - return RETURN_OK; - } - case (StarTracker::REQ_VERSION): { - prepareVersionRequest(); - return RETURN_OK; - } - case (StarTracker::REQ_INTERFACE): { - prepareInterfaceRequest(); - return RETURN_OK; - } - case (StarTracker::REQ_POWER): { - preparePowerRequest(); - return RETURN_OK; - } - case (StarTracker::SWITCH_TO_BOOTLOADER_PROGRAM): { - prepareRebootCommand(); - return RETURN_OK; - } - case (StarTracker::TAKE_IMAGE): { - prepareTakeImageCommand(commandData); - return RETURN_OK; - } - case (StarTracker::SUBSCRIBE_TO_TM): { - prepareSubscriptionCommand(commandData); - return RETURN_OK; - } - case (StarTracker::REQ_SOLUTION): { - prepareSolutionRequest(); - return RETURN_OK; - } - case (StarTracker::REQ_TEMPERATURE): { - prepareTemperatureRequest(); - return RETURN_OK; - } - case (StarTracker::REQ_HISTOGRAM): { - prepareHistogramRequest(); - return RETURN_OK; - } - case (StarTracker::REQ_CONTRAST): { - prepareContrastRequest(); - return RETURN_OK; - } - case (StarTracker::RESET_ERROR): { - prepareErrorResetRequest(); - return RETURN_OK; - } - case (StarTracker::LIMITS): { - Limits limits; - result = prepareParamCommand(commandData, commandDataLen, limits); - return result; - } - case (StarTracker::MOUNTING): { - Mounting mounting; - result = prepareParamCommand(commandData, commandDataLen, mounting); - return result; - } - case (StarTracker::CAMERA): { - Camera camera; - result = prepareParamCommand(commandData, commandDataLen, camera); - return result; - } - case (StarTracker::BLOB): { - Blob blob; - result = prepareParamCommand(commandData, commandDataLen, blob); - return result; - } - case (StarTracker::CENTROIDING): { - Centroiding centroiding; - result = prepareParamCommand(commandData, commandDataLen, centroiding); - return result; - } - case (StarTracker::LISA): { - Lisa lisa; - result = prepareParamCommand(commandData, commandDataLen, lisa); - return result; - } - case (StarTracker::MATCHING): { - Matching matching; - result = prepareParamCommand(commandData, commandDataLen, matching); - return result; - } - case (StarTracker::VALIDATION): { - Validation validation; - result = prepareParamCommand(commandData, commandDataLen, validation); - return result; - } - case (StarTracker::ALGO): { - Algo algo; - result = prepareParamCommand(commandData, commandDataLen, algo); - return result; - } - case (StarTracker::TRACKING): { - Tracking tracking; - result = prepareParamCommand(commandData, commandDataLen, tracking); - return result; - } - case (StarTracker::ERASE): { - result = prepareEraseCommand(commandData, commandDataLen); - return result; - } - case (StarTracker::UNLOCK): { - result = prepareUnlockCommand(commandData, commandDataLen); - return result; - } - case (StarTracker::CHECKSUM): { - result = prepareChecksumCommand(commandData, commandDataLen); - return result; - } - case (StarTracker::SET_TIME): { - result = prepareSetTimeCommand(commandData, commandDataLen); - return result; - } - case (StarTracker::DOWNLOAD_CENTROID): { - result = prepareDownloadCentroidCommand(commandData, commandDataLen); - return result; - } - case (StarTracker::UPLOAD_CENTROID): { - result = prepareUploadCentroidCommand(commandData, commandDataLen); - return result; - } - case (StarTracker::DOWNLOAD_MATCHED_STAR): { - result = prepareDownloadMatchedStarCommand(commandData, commandDataLen); - return result; - } - case (StarTracker::DOWNLOAD_DBIMAGE): { - result = prepareDownloadDbImageCommand(commandData, commandDataLen); - return result; - } - case (StarTracker::DOWNLOAD_BLOBPIXEL): { - result = prepareDownloadBlobPixelCommand(commandData, commandDataLen); - return result; - } - case (StarTracker::FPGA_ACTION): { - result = prepareFpgaActionCommand(commandData, commandDataLen); - return result; - } - default: - return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; - } - return HasReturnvaluesIF::RETURN_FAILED; -} - -void StarTrackerHandler::fillCommandAndReplyMap() { - /** Reply lengths are unknown because of the slip encoding. Thus always maximum reply size - * is specified */ - this->insertInCommandAndReplyMap(StarTracker::PING_REQUEST, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandMap(StarTracker::BOOT); - this->insertInCommandAndReplyMap(StarTracker::REQ_VERSION, 3, &versionSet, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::REQ_TIME, 3, &timeSet, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandMap(StarTracker::UPLOAD_IMAGE); - this->insertInCommandMap(StarTracker::DOWNLOAD_IMAGE); - this->insertInCommandAndReplyMap(StarTracker::REQ_POWER, 3, &powerSet, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::REQ_INTERFACE, 3, &interfaceSet, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - // Reboot has no reply. Star tracker reboots immediately - this->insertInCommandMap(StarTracker::SWITCH_TO_BOOTLOADER_PROGRAM); - this->insertInCommandAndReplyMap(StarTracker::SUBSCRIBE_TO_TM, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::REQ_SOLUTION, 3, &solutionSet, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::REQ_TEMPERATURE, 3, &temperatureSet, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::REQ_HISTOGRAM, 3, &histogramSet, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::REQ_CONTRAST, 3, &contrastSet, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::LIMITS, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::MOUNTING, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::CAMERA, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::BLOB, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::CENTROIDING, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::LISA, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::MATCHING, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::TRACKING, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::VALIDATION, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::ALGO, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::TAKE_IMAGE, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::RESET_ERROR, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::ERASE, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::UNLOCK, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::CHECKSUM, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::SET_TIME, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::DOWNLOAD_CENTROID, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::UPLOAD_CENTROID, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::DOWNLOAD_MATCHED_STAR, 3, &downloadMatchedStar, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::DOWNLOAD_DBIMAGE, 3, &downloadDbImage, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::DOWNLOAD_BLOBPIXEL, 3, &downloadBlobPixel, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::FPGA_ACTION, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); -} - -ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t remainingSize, - DeviceCommandId_t *foundId, size_t *foundLen) { - - ReturnValue_t result = RETURN_OK; - size_t bytesLeft = 0; - - result = dataLinkLayer.decodeFrame(start, remainingSize, &bytesLeft); - switch(result) { - case ArcsecDatalinkLayer::DEC_IN_PROGRESS: { - remainingSize = bytesLeft; - // Need a second doSendRead pass to reaa in whole packet - return IGNORE_REPLY_DATA; - } - case RETURN_OK: { - break; - } - default: - remainingSize = bytesLeft; - return result; - } - - switch (dataLinkLayer.getReplyFrameType()) { - case TMTC_ACTIONREPLY: { - *foundLen = remainingSize - bytesLeft; - result = scanForActionReply(foundId); - break; - } - case TMTC_SETPARAMREPLY: { - *foundLen = remainingSize - bytesLeft; - result = scanForParameterReply(foundId); - break; - } - case TMTC_TELEMETRYREPLYA: - case TMTC_TELEMETRYREPLY: { - *foundLen = remainingSize - bytesLeft; - result = scanForTmReply(foundId); - break; - } - default: { - sif::debug << "StarTrackerHandler::scanForReply: Reply has invalid type id" << std::endl; - result = RETURN_FAILED; - } - } - - remainingSize = bytesLeft; - - return result; -} - -ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { - - ReturnValue_t result = RETURN_OK; - - switch (id) { - case (StarTracker::SUBSCRIBE_TO_TM): { - result = handleSetParamReply(); - break; - } - case (StarTracker::REQ_TIME): { - result = handleTm(timeSet, StarTracker::TimeSet::SIZE); - break; - } - case (StarTracker::PING_REQUEST): { - result = handlePingReply(); - break; - } - case (StarTracker::BOOT): - case (StarTracker::TAKE_IMAGE): - case (StarTracker::RESET_ERROR): - case (StarTracker::UNLOCK): - case (StarTracker::SET_TIME): - case (StarTracker::FPGA_ACTION): { - result = handleActionReply(); - break; - } - case (StarTracker::DOWNLOAD_CENTROID): { - result = handleActionReplySet(downloadCentroidSet, StarTracker::DownloadCentroidSet::SIZE); - break; - } - case (StarTracker::DOWNLOAD_MATCHED_STAR): { - result = handleActionReplySet(downloadMatchedStar, StarTracker::DownloadMatchedStar::SIZE); - break; - } - case (StarTracker::DOWNLOAD_DBIMAGE): { - result = handleActionReplySet(downloadDbImage, StarTracker::DownloadDBImage::SIZE); - break; - } - case (StarTracker::DOWNLOAD_BLOBPIXEL): { - result = handleActionReplySet(downloadBlobPixel, StarTracker::DownloadBlobPixel::SIZE); - break; - } - case (StarTracker::UPLOAD_CENTROID): { - result = handleUploadCentroidReply(); - break; - } - case (StarTracker::ERASE): { - result = handleEraseReply(); - break; - } - case (StarTracker::CHECKSUM): { - result = handleChecksumReply(); - break; - } - case (StarTracker::REQ_VERSION): { - result = handleTm(versionSet, StarTracker::VersionSet::SIZE); - if (result != RETURN_OK) { - return result; - } - result = checkProgram(); - if (result != RETURN_OK) { - return result; - } - break; - } - case (StarTracker::REQ_INTERFACE): { - result = handleTm(interfaceSet, StarTracker::InterfaceSet::SIZE); - break; - } - case (StarTracker::REQ_POWER): { - result = handleTm(powerSet, StarTracker::PowerSet::SIZE); - break; - } - case (StarTracker::REQ_SOLUTION): { - result = handleTm(solutionSet, StarTracker::SolutionSet::SIZE); - break; - } - case (StarTracker::REQ_TEMPERATURE): { - result = handleTm(temperatureSet, StarTracker::TemperatureSet::SIZE); - break; - } - case (StarTracker::REQ_HISTOGRAM): { - result = handleTm(histogramSet, StarTracker::HistogramSet::SIZE); - break; - } - case (StarTracker::REQ_CONTRAST): { - result = handleTm(contrastSet, StarTracker::ContrastSet::SIZE); - break; - } - case (StarTracker::LIMITS): - case (StarTracker::MOUNTING): - case (StarTracker::CAMERA): - case (StarTracker::BLOB): - case (StarTracker::CENTROIDING): - case (StarTracker::LISA): - case (StarTracker::MATCHING): - case (StarTracker::TRACKING): - case (StarTracker::VALIDATION): - case (StarTracker::ALGO): { - result = handleSetParamReply(); - break; - } - default: { - sif::debug << "StarTrackerHandler::interpretDeviceReply: Unknown device reply id:" << id - << std::endl; - result = DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; - } - } - - return result; -} - - -void StarTrackerHandler::setNormalDatapoolEntriesInvalid() { - -} - -uint32_t StarTrackerHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { - return 20000; -} - -ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) { - - localDataPoolMap.emplace(StarTracker::TICKS_TIME_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TIME_TIME_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::RUN_TIME, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::UNIX_TIME, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(StarTracker::TICKS_VERSION_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TIME_VERSION_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::PROGRAM, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MAJOR, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MINOR, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(StarTracker::TICKS_INTERFACE_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TIME_INTERFACE_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::FRAME_COUNT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CHECKSUM_ERROR_COUNT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::SET_PARAM_COUNT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::SET_PARAM_REPLY_COUNT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::PARAM_REQUEST_COUNT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::PARAM_REPLY_COUNT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::REQ_TM_COUNT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TM_REPLY_COUNT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::ACTION_REQ_COUNT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::ACTION_REPLY_COUNT, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(StarTracker::TICKS_POWER_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TIME_POWER_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MCU_CURRENT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MCU_VOLTAGE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::FPGA_CORE_CURRENT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::FPGA_CORE_VOLTAGE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::FPGA_18_CURRENT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::FPGA_18_VOLTAGE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::FPGA_25_CURRENT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::FPGA_25_VOLTAGE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CMV_21_CURRENT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CMV_21_VOLTAGE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CMV_PIX_CURRENT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CMV_PIX_VOLTAGE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CMV_33_CURRENT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CMV_33_VOLTAGE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CMV_RES_CURRENT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CMV_RES_VOLTAGE, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(StarTracker::TICKS_TEMPERATURE_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TIME_TEMPERATURE_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MCU_TEMPERATURE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CMOS_TEMPERATURE, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(StarTracker::TICKS_SOLUTION_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TIME_SOLUTION_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CALI_QW, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CALI_QX, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CALI_QY, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CALI_QZ, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TRACK_CONFIDENCE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TRACK_QW, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TRACK_QX, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TRACK_QY, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TRACK_QZ, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TRACK_REMOVED, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::STARS_CENTROIDED, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::STARS_MATCHED_DATABASE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::LISA_QW, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::LISA_QX, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::LISA_QY, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::LISA_QZ, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::LISA_PERC_CLOSE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::LISA_NR_CLOSE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TRUST_WORTHY, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::STABLE_COUNT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::SOLUTION_STRATEGY, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(StarTracker::TICKS_HISTOGRAM_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TIME_HISTOGRAM_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA0, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA1, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA2, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA3, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA4, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA5, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA7, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA8, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB0, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB1, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB2, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB3, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB4, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB5, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB7, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB8, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC0, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC1, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC2, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC3, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC4, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC5, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC7, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC8, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND0, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND1, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND2, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND3, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND4, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND5, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND7, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND8, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(StarTracker::TICKS_CONTRAST_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TIME_CONTRAST_SET, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINA0, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINA1, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINA2, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINA3, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINA4, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINA5, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINA6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINA7, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINA8, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINB0, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINB1, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINB2, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINB3, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINB4, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINB5, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINB6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINB7, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINB8, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINC8, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINC0, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINC1, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINC2, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINC3, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINC4, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINC5, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINC6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINC7, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BINC8, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BIND0, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BIND1, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BIND2, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BIND3, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BIND4, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BIND5, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BIND6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BIND7, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CONTRAST_BIND8, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::CHKSUM, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(StarTracker::DWL_ID, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::DWL_PIXX, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::DWL_PIXY, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::DWL_X_UNCORRECTED, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::DWL_Y_UNCORRECTED, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::DWL_X_CORRECTED, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::DWL_Y_CORRECTED, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::DWL_MAGNITUDE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::DWL_CXA, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::DWL_CYA, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::DWL_QUALITY, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_ID, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMFPX, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMFPY, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMCARTX, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMCARTY, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMCARTZ, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMMAGNITUDE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBFPX, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBFPY, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBCARTX, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBCARTY, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBCARTZ, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBMAGNITUDE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CATALOGID, new PoolEntry( { 0 })); - - localDataPoolMap.emplace(StarTracker::BLOBPIX_ID, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::BLOBPIX_X, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::BLOBPIX_Y, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::BLOBPIX_TOT_VAL, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::BLOBPIX_IN_USE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::BLOBPIX_BRIGHT_NEIGHBOURS, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::BLOBPIX_REGION, new PoolEntry( { 0 })); - return RETURN_OK; -} - -size_t StarTrackerHandler::getNextReplyLength(DeviceCommandId_t commandId){ - return StarTracker::MAX_FRAME_SIZE; -} - -ReturnValue_t StarTrackerHandler::doSendReadHook() { - // Prevent DHB from polling UART during commands executed by the image loader task - if(strHelperExecuting) { - return RETURN_FAILED; - } - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::checkMode(ActionId_t actionId) { - switch(actionId) { - case StarTracker::UPLOAD_IMAGE: - case StarTracker::DOWNLOAD_IMAGE: { - return DeviceHandlerBase::acceptExternalDeviceCommands(); - default: - break; - } - } - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId) { - const uint8_t* reply = dataLinkLayer.getReply(); - switch (*reply) { - case (StarTracker::ID::PING): { - *foundId = StarTracker::PING_REQUEST; - break; - } - case (StarTracker::ID::WRITE): { - *foundId = StarTracker::WRITE; - break; - } - case (StarTracker::ID::BOOT): { - *foundId = StarTracker::BOOT; - break; - } - case (StarTracker::ID::TAKE_IMAGE): { - *foundId = StarTracker::TAKE_IMAGE; - break; - } - case (StarTracker::ID::UPLOAD_IMAGE): { - *foundId = StarTracker::UPLOAD_IMAGE; - break; - } - case (StarTracker::ID::ERROR_RESET): { - *foundId = StarTracker::RESET_ERROR; - break; - } - case (StarTracker::ID::ERASE): { - *foundId = StarTracker::ERASE; - break; - } - case (StarTracker::ID::UNLOCK): { - *foundId = StarTracker::UNLOCK; - break; - } - case (StarTracker::ID::CHECKSUM): { - *foundId = StarTracker::CHECKSUM; - break; - } - case (StarTracker::ID::SET_TIME): { - *foundId = StarTracker::SET_TIME; - break; - } - case (StarTracker::ID::DOWNLOAD_CENTROID): { - *foundId = StarTracker::DOWNLOAD_CENTROID; - break; - } - case (StarTracker::ID::UPLOAD_CENTROID): { - *foundId = StarTracker::UPLOAD_CENTROID; - break; - } - case (StarTracker::ID::DOWNLOAD_MATCHED_STAR): { - *foundId = StarTracker::DOWNLOAD_MATCHED_STAR; - break; - } - case (StarTracker::ID::DOWNLOAD_DBIMAGE): { - *foundId = StarTracker::DOWNLOAD_DBIMAGE; - break; - } - case (StarTracker::ID::DOWNLOAD_BLOBPIXEL): { - *foundId = StarTracker::DOWNLOAD_BLOBPIXEL; - break; - } - case (StarTracker::ID::FPGA_ACTION): { - *foundId = StarTracker::FPGA_ACTION; - break; - } - default: - sif::warning << "StarTrackerHandler::scanForParameterReply: Unknown parameter reply id" - << std::endl; - return RETURN_FAILED; - } - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::scanForParameterReply(DeviceCommandId_t *foundId) { - const uint8_t* reply = dataLinkLayer.getReply(); - switch (*reply) { - case (StarTracker::ID::SUBSCRIBE): { - *foundId = StarTracker::SUBSCRIBE_TO_TM; - break; - } - case (StarTracker::ID::LIMITS): { - *foundId = StarTracker::LIMITS; - break; - } - case (StarTracker::ID::MOUNTING): { - *foundId = StarTracker::MOUNTING; - break; - } - case (StarTracker::ID::CAMERA): { - *foundId = StarTracker::CAMERA; - break; - } - case (StarTracker::ID::BLOB): { - *foundId = StarTracker::BLOB; - break; - } - case (StarTracker::ID::CENTROIDING): { - *foundId = StarTracker::CENTROIDING; - break; - } - case (StarTracker::ID::LISA): { - *foundId = StarTracker::LISA; - break; - } - case (StarTracker::ID::MATCHING): { - *foundId = StarTracker::MATCHING; - break; - } - case (StarTracker::ID::TRACKING): { - *foundId = StarTracker::TRACKING; - break; - } - case (StarTracker::ID::VALIDATION): { - *foundId = StarTracker::VALIDATION; - break; - } - case (StarTracker::ID::ALGO): { - *foundId = StarTracker::ALGO; - break; - } - default: - sif::debug << "StarTrackerHandler::scanForParameterReply: Unknown parameter reply id" - << std::endl; - return RETURN_FAILED; - } - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::scanForTmReply(DeviceCommandId_t *foundId) { - const uint8_t* reply = dataLinkLayer.getReply(); - switch (*reply) { - case (StarTracker::ID::VERSION): { - *foundId = StarTracker::REQ_VERSION; - break; - } - case (StarTracker::ID::INTERFACE): { - *foundId = StarTracker::REQ_INTERFACE; - break; - } - case (StarTracker::ID::POWER): { - *foundId = StarTracker::REQ_POWER; - break; - } - case (StarTracker::ID::TEMPERATURE): { - *foundId = StarTracker::REQ_TEMPERATURE; - break; - } - case (StarTracker::ID::HISTOGRAM): { - *foundId = StarTracker::REQ_HISTOGRAM; - break; - } - case (StarTracker::ID::CONTRAST): { - *foundId = StarTracker::REQ_CONTRAST; - break; - } - case (StarTracker::ID::TIME): { - *foundId = StarTracker::REQ_TIME; - break; - } - case (StarTracker::ID::SOLUTION): { - *foundId = StarTracker::REQ_SOLUTION; - break; - } - default: { - sif::debug << "StarTrackerHandler::scanForTmReply: Reply contains invalid reply id" - << std::endl; - return RETURN_FAILED; - break; - } - } - return RETURN_OK; -} - -void StarTrackerHandler::handleEvent(EventMessage* eventMessage) { - object_id_t objectId = eventMessage->getReporter(); - switch(objectId){ - case objects::STR_HELPER: { - // All events from image loader signal either that the operation was successful or that it - // failed - strHelperExecuting = false; - break; - } - default: - sif::debug << "StarTrackerHandler::handleEvent: Did not subscribe to this event" - << std::endl; - break; - } -} - -ReturnValue_t StarTrackerHandler::executeWriteCommand(const uint8_t* commandData, - size_t commandDataLen) { - ReturnValue_t result = RETURN_OK; - if (commandDataLen < WriteCmd::MIN_LENGTH) { - sif::warning << "StarTrackerHandler::executeWriteCommand: Command too short" << std::endl; - return COMMAND_TOO_SHORT; - } - uint8_t region = *(commandData); - uint32_t address; - size_t size = sizeof(address); - const uint8_t* addressPtr = commandData + WriteCmd::ADDRESS_OFFSET; - result = SerializeAdapter::deSerialize(&address, addressPtr, &size, - SerializeIF::Endianness::BIG); - if (result != RETURN_OK) { - sif::debug << "StarTrackerHandler::executeWriteCommand: Deserialization of address failed" - << std::endl; - return result; - } - if (commandDataLen - sizeof(address) - sizeof(region) > MAX_PATH_SIZE) { - sif::warning << "StarTrackerHandler::executeWriteCommand: Received command with invalid" - << " path and filename" << std::endl; - return FILE_PATH_TOO_LONG; - } - const uint8_t* filePtr = commandData + WriteCmd::FILE_OFFSET; - std::string fullname = std::string(reinterpret_cast(filePtr), - commandDataLen - sizeof(address) - sizeof(region)); - result = strHelper->startFlashWrite(fullname, region, address); - if (result != RETURN_OK) { - return result; - } - return result; -} - -ReturnValue_t StarTrackerHandler::executeFpgaDownloadCommand(const uint8_t* commandData, - size_t commandDataLen) { - ReturnValue_t result = RETURN_OK; - if (commandDataLen < FpgaDownloadCmd::MIN_LENGTH) { - sif::warning << "StarTrackerHandler::executeFpgaDownloadCommand: Command too short" - << std::endl; - return COMMAND_TOO_SHORT; - } - uint32_t position; - size_t size = sizeof(position); - result = SerializeAdapter::deSerialize(&position, &commandData, &size, - SerializeIF::Endianness::BIG); - if (result != RETURN_OK) { - sif::debug << "StarTrackerHandler::executeWriteCommand: Deserialization of position failed" - << std::endl; - return result; - } - uint32_t length; - size = sizeof(length); - result = SerializeAdapter::deSerialize(&length, &commandData, &size, - SerializeIF::Endianness::BIG); - if (result != RETURN_OK) { - sif::debug << "StarTrackerHandler::executeWriteCommand: Deserialization of length failed" - << std::endl; - return result; - } - if (commandDataLen - sizeof(position) - sizeof(length) > MAX_PATH_SIZE) { - sif::warning << "StarTrackerHandler::executeFpgaDownloadCommand: Received command with " - " invalid path and filename" << std::endl; - return FILE_PATH_TOO_LONG; - } - std::string fullname = std::string(reinterpret_cast(commandData), - commandDataLen - sizeof(position) - sizeof(length)); - result = strHelper->startFpgaDownload(fullname, position, length); - if (result != RETURN_OK) { - return result; - } - return result; -} - -ReturnValue_t StarTrackerHandler::executeReadCommand(const uint8_t* commandData, - size_t commandDataLen) { - ReturnValue_t result = RETURN_OK; - if (commandDataLen < ReadCmd::MIN_LENGTH) { - sif::warning << "StarTrackerHandler::executeReadCommand: Command too short" << std::endl; - return COMMAND_TOO_SHORT; - } - uint8_t region = *(commandData); - uint32_t address; - size_t size = sizeof(address); - const uint8_t* addressPtr = commandData + ReadCmd::ADDRESS_OFFSET; - result = SerializeAdapter::deSerialize(&address, addressPtr, &size, - SerializeIF::Endianness::BIG); - if (result != RETURN_OK) { - sif::debug << "StarTrackerHandler::executeReadCommand: Deserialization of address failed" - << std::endl; - return result; - } - uint32_t length; - size = sizeof(length); - const uint8_t* lengthPtr = commandData + ReadCmd::LENGTH_OFFSET; - result = SerializeAdapter::deSerialize(&length, lengthPtr, &size, - SerializeIF::Endianness::BIG); - if (result != RETURN_OK) { - sif::debug << "StarTrackerHandler::executeReadCommand: Deserialization of length failed" - << std::endl; - return result; - } - if (commandDataLen - sizeof(address) - sizeof(region) - sizeof(length) > MAX_PATH_SIZE) { - sif::warning << "StarTrackerHandler::executeReadCommand: Received command with invalid" - << " path and filename" << std::endl; - return FILE_PATH_TOO_LONG; - } - const uint8_t* filePtr = commandData + ReadCmd::FILE_OFFSET; - std::string fullname = std::string(reinterpret_cast(filePtr), - commandDataLen - sizeof(address) - sizeof(region) - sizeof(length)); - result = strHelper->startFlashRead(fullname, region, address, length); - if (result != RETURN_OK) { - return result; - } - return result; -} - -void StarTrackerHandler::prepareBootCommand() { - uint32_t length = 0; - struct BootActionRequest bootRequest = {BOOT_REGION_ID}; - arc_pack_boot_action_req(&bootRequest, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -ReturnValue_t StarTrackerHandler::prepareEraseCommand(const uint8_t* commandData, - size_t commandDataLen) { - ReturnValue_t result = RETURN_OK; - if (commandDataLen != EraseCmd::LENGTH) { - return INVALID_LENGTH; - } - uint32_t length = 0; - struct EraseActionRequest req; - req.region = *commandData; - arc_pack_erase_action_req(&req, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - eraseCmd.rememberRegion = req.region; - return result; -} - -ReturnValue_t StarTrackerHandler::prepareUnlockCommand(const uint8_t* commandData, - size_t commandDataLen) { - ReturnValue_t result = RETURN_OK; - uint32_t length = 0; - struct UnlockActionRequest req; - req.region = *commandData; - size_t size = sizeof(req.code); - const uint8_t* codePtr = commandData + UnlockCmd::CODE_OFFSET; - result = SerializeAdapter::deSerialize(&req.code, &codePtr, &size, - SerializeIF::Endianness::BIG); - if (result != RETURN_OK) { - return result; - } - arc_pack_unlock_action_req(&req, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - return result; -} - -ReturnValue_t StarTrackerHandler::prepareChecksumCommand(const uint8_t* commandData, - size_t commandDataLen) { - struct ChecksumActionRequest req; - ReturnValue_t result = RETURN_OK; - if (commandDataLen != ChecksumCmd::LENGTH) { - sif::warning << "StarTrackerHandler::prepareChecksumCommand: Invalid length" << std::endl; - return INVALID_LENGTH; - } - req.region = *(commandData); - size_t size = sizeof(req.address); - const uint8_t* addressPtr = commandData + ChecksumCmd::ADDRESS_OFFSET; - result = SerializeAdapter::deSerialize(&req.address, addressPtr, &size, - SerializeIF::Endianness::BIG); - if (result != RETURN_OK) { - sif::debug << "StarTrackerHandler::prepareChecksumCommand: Deserialization of address " - << "failed" << std::endl; - return result; - } - size = sizeof(req.length); - const uint8_t* lengthPtr = commandData + ChecksumCmd::LENGTH_OFFSET; - result = SerializeAdapter::deSerialize(&req.length, lengthPtr, &size, - SerializeIF::Endianness::BIG); - if (result != RETURN_OK) { - sif::debug << "StarTrackerHandler::prepareChecksumCommand: Deserialization of length failed" - << std::endl; - return result; - } - uint32_t rawCmdLength = 0; - arc_pack_checksum_action_req(&req, commandBuffer, &rawCmdLength); - dataLinkLayer.encodeFrame(commandBuffer, rawCmdLength); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - checksumCmd.rememberRegion = req.region; - checksumCmd.rememberAddress = req.address; - checksumCmd.rememberLength = req.length; - return result; -} - - -ReturnValue_t StarTrackerHandler::prepareSetTimeCommand(const uint8_t* commandData, - size_t commandDataLen) { - ReturnValue_t result = RETURN_OK; - struct SetTimeActionRequest req; - if (commandDataLen != SetTimeCmd::LENGTH) { - sif::warning << "StarTrackerHandler::prepareSetTimeCommand: Invalid length" << std::endl; - return INVALID_LENGTH; - } - size_t size = sizeof(req.unixTime); - result = SerializeAdapter::deSerialize(&req.unixTime, commandData, &size, - SerializeIF::Endianness::BIG); - if (result != RETURN_OK) { - sif::debug << "StarTrackerHandler::prepareSetTimeCommand: Deserialization failed" - << std::endl; - return result; - } - uint32_t length = 0; - arc_pack_settime_action_req(&req, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - return result; -} - -ReturnValue_t StarTrackerHandler::prepareDownloadCentroidCommand(const uint8_t* commandData, - size_t commandDataLen) { - ReturnValue_t result = RETURN_OK; - struct DownloadCentroidActionRequest req; - if (commandDataLen != DownloadCentroidCmd::LENGTH) { - sif::warning << "StarTrackerHandler::prepareDownloadCentroidCommand: Invalid length" - << std::endl; - return INVALID_LENGTH; - } - req.id = *commandData; - uint32_t length = 0; - arc_pack_downloadcentroid_action_req(&req, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - return result; -} - -ReturnValue_t StarTrackerHandler::prepareUploadCentroidCommand(const uint8_t* commandData, - size_t commandDataLen) { - if (commandDataLen > MAX_PATH_SIZE) { - return FILE_PATH_TOO_LONG; - } - ReturnValue_t result = RETURN_OK; - struct UploadCentroidActionRequest req; - std::string jsonFileName = std::string(reinterpret_cast(commandData), - commandDataLen); - NVMParameterBase j(jsonFileName); - result = j.readJsonFile(); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: " << jsonFileName - << " does not exist" << std::endl; - return result; - } - result = j.getValue(StarTracker::UploadCentroidKeys::id, &req.id); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " - << StarTracker::UploadCentroidKeys::id << " does not exist" << std::endl; - return result; - } - result = j.getValue(StarTracker::UploadCentroidKeys::pixx, &req.pixx); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " - << StarTracker::UploadCentroidKeys::pixx << " does not exist" << std::endl; - return result; - } - result = j.getValue(StarTracker::UploadCentroidKeys::pixy, &req.pixy); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " - << StarTracker::UploadCentroidKeys::pixy << " does not exist" << std::endl; - return result; - } - result = j.getValue(StarTracker::UploadCentroidKeys::x_uncorrected, &req.x_uncorrected); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " - << StarTracker::UploadCentroidKeys::x_uncorrected << " does not exist" << std::endl; - return result; - } - result = j.getValue(StarTracker::UploadCentroidKeys::y_uncorrected, &req.y_uncorrected); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " - << StarTracker::UploadCentroidKeys::y_uncorrected << " does not exist" << std::endl; - return result; - } - result = j.getValue(StarTracker::UploadCentroidKeys::x_corrected, &req.x_corrected); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " - << StarTracker::UploadCentroidKeys::x_corrected << " does not exist" << std::endl; - return result; - } - result = j.getValue(StarTracker::UploadCentroidKeys::y_corrected, &req.y_corrected); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " - << StarTracker::UploadCentroidKeys::y_corrected << " does not exist" << std::endl; - return result; - } - result = j.getValue(StarTracker::UploadCentroidKeys::magnitude, &req.magnitude); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " - << StarTracker::UploadCentroidKeys::magnitude << " does not exist" << std::endl; - return result; - } - result = j.getValue(StarTracker::UploadCentroidKeys::cxa, &req.cxa); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " - << StarTracker::UploadCentroidKeys::cxa << " does not exist" << std::endl; - return result; - } - result = j.getValue(StarTracker::UploadCentroidKeys::cya, &req.cya); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " - << StarTracker::UploadCentroidKeys::cya << " does not exist" << std::endl; - return result; - } - result = j.getValue(StarTracker::UploadCentroidKeys::quality, &req.quality); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " - << StarTracker::UploadCentroidKeys::quality << " does not exist" << std::endl; - return result; - } - uint32_t length = 0; - arc_pack_uploadcentroid_action_req(&req, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - uploadCentroid.rememberId = req.id; - return result; -} - -void StarTrackerHandler::prepareTimeRequest() { - uint32_t length = 0; - arc_tm_pack_time_req(commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::preparePingRequest() { - uint32_t length = 0; - struct PingActionRequest pingRequest = {PING_ID}; - arc_pack_ping_action_req(&pingRequest, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::prepareVersionRequest() { - uint32_t length = 0; - arc_tm_pack_version_req(commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::prepareInterfaceRequest() { - uint32_t length = 0; - arc_tm_pack_interface_req(commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::preparePowerRequest() { - uint32_t length = 0; - arc_tm_pack_power_req(commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::prepareRebootCommand() { - uint32_t length = 0; - struct RebootActionRequest rebootReq; - arc_pack_reboot_action_req(&rebootReq, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::prepareTakeImageCommand(const uint8_t* commandData) { - uint32_t length = 0; - struct CameraActionRequest camReq; - camReq.actionid = *commandData; - arc_pack_camera_action_req(&camReq, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::prepareSubscriptionCommand(const uint8_t* tmId) { - uint32_t length = 18; - commandBuffer[0] = TMTC_SETPARAMREQ; - commandBuffer[1] = StarTracker::ID::SUBSCRIBE; - // Fill all other fields with invalid tm id - commandBuffer[2] = *tmId; - commandBuffer[3] = 0; - commandBuffer[4] = 0; - commandBuffer[5] = 0; - commandBuffer[6] = 0; - commandBuffer[7] = 0; - commandBuffer[8] = 0; - commandBuffer[9] = 0; - commandBuffer[10] = 0; - commandBuffer[11] = 0; - commandBuffer[12] = 0; - commandBuffer[13] = 0; - commandBuffer[14] = 0; - commandBuffer[15] = 0; - commandBuffer[16] = 0; - commandBuffer[17] = 0; - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::prepareSolutionRequest() { - uint32_t length = 0; - arc_tm_pack_solution_req(commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::prepareTemperatureRequest() { - uint32_t length = 0; - arc_tm_pack_temperature_req(commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::prepareHistogramRequest() { - uint32_t length = 0; - arc_tm_pack_histogram_req(commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::prepareContrastRequest() { - uint32_t length = 0; - arc_tm_pack_contrast_req(commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -void StarTrackerHandler::prepareErrorResetRequest() { - uint32_t length = 0; - struct ResetErrorSignalActionRequest req; - arc_pack_reseterrorsignal_action_req(&req, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); -} - -ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData, - size_t commandDataLen, ArcsecJsonParamBase& paramSet) { - ReturnValue_t result = RETURN_OK; - if (commandDataLen > MAX_PATH_SIZE) { - return FILE_PATH_TOO_LONG; - } - std::string fullName(reinterpret_cast(commandData), commandDataLen); - - result = paramSet.create(fullName, commandBuffer); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareParamCommand: Failed to create parameter " - "command" << std::endl; - return result; - } - dataLinkLayer.encodeFrame(commandBuffer, paramSet.getSize()); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::prepareDownloadMatchedStarCommand(const uint8_t* commandData, - size_t commandDataLen) { - if (commandDataLen != DownloadMatchedStarCmd::LENGTH) { - return INVALID_LENGTH; - } - struct DownloadMatchedStarActionRequest req; - req.id = *commandData; - uint32_t length = 0; - arc_pack_downloadmatchedstar_action_req(&req, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::prepareDownloadDbImageCommand(const uint8_t* commandData, - size_t commandDataLen) { - if (commandDataLen != DownloadDbImageCmd::LENGTH) { - return INVALID_LENGTH; - } - struct DownloadDBImageActionRequest req; - req.id = *commandData; - uint32_t length = 0; - arc_pack_downloaddbimage_action_req(&req, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::prepareDownloadBlobPixelCommand(const uint8_t* commandData, - size_t commandDataLen) { - if (commandDataLen != DownloadBlobPixCmd::LENGTH) { - return INVALID_LENGTH; - } - struct DownloadBlobPixelActionRequest req; - req.id = *commandData; - req.type = *(commandData + 1); - if ((req.type != DownloadBlobPixCmd::NORMAL) && (req.type != DownloadBlobPixCmd::FAST)) { - return INVALID_TYPE; - } - uint32_t length = 0; - arc_pack_downloadblobpixel_action_req(&req, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::prepareFpgaActionCommand(const uint8_t* commandData, - size_t commandDataLen) { - if (commandDataLen != FpgaActionCmd::LENGTH) { - return INVALID_LENGTH; - } - struct FPGAActionActionRequest req; - req.id = *commandData; - if (req.id != FpgaActionCmd::ID) { - return INVALID_ID; - } - uint32_t length = 0; - arc_pack_fpgaaction_action_req(&req, commandBuffer, &length); - dataLinkLayer.encodeFrame(commandBuffer, length); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::handleSetParamReply() { - const uint8_t* reply = dataLinkLayer.getReply(); - uint8_t status = *(reply + STATUS_OFFSET); - if (status != StarTracker::STATUS_OK) { - sif::warning << "StarTrackerHandler::handleSetParamReply: Failed to execute parameter set " - " command with parameter ID" << - static_cast(*(reply + PARAMETER_ID_OFFSET)) << std::endl; - if (startupState != StartupState::IDLE) { - startupState = StartupState::IDLE; - } - return SET_PARAM_FAILED; - } - if (startupState != StartupState::IDLE) { - handleStartup(reply + PARAMETER_ID_OFFSET); - } - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::handleActionReply() { - const uint8_t* reply = dataLinkLayer.getReply(); - uint8_t status = *(reply + STATUS_OFFSET); - if (status != StarTracker::STATUS_OK) { - sif::warning << "StarTrackerHandler::handleActionReply: Failed to execute action " - << "command with action ID " - << static_cast(*(reply + ACTION_ID_OFFSET)) - << " and status "<< static_cast(status) << std::endl; - return ACTION_FAILED; - } - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::handleUploadCentroidReply() { - ReturnValue_t result = RETURN_OK; - result = handleActionReply(); - if (result != RETURN_OK) { - return result; - } - const uint8_t* reply = dataLinkLayer.getReply(); - if (*(reply + ACTION_DATA_OFFSET) != uploadCentroid.rememberId) { - return UPLOAD_CENTROID_ID_MISMATCH; - } - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::handleEraseReply() { - ReturnValue_t result = RETURN_OK; - result = handleActionReply(); - if (result != RETURN_OK) { - return result; - } - const uint8_t* replyData = dataLinkLayer.getReply() + ACTION_DATA_OFFSET; - StarTracker::EraseReply eraseReply(replyData); - if (eraseReply.getRegion() != eraseCmd.rememberRegion) { - sif::warning << "StarTrackerHandler::handleEraseReply: Region mismatch" << std::endl; - return REGION_MISMATCH; - } - return result; -} - -ReturnValue_t StarTrackerHandler::handleChecksumReply() { - ReturnValue_t result = RETURN_OK; - result = handleActionReply(); - if (result != RETURN_OK) { - return result; - } - const uint8_t* replyData = dataLinkLayer.getReply() + ACTION_DATA_OFFSET; - StarTracker::ChecksumReply checksumReply(replyData); - if (checksumReply.getRegion() != checksumCmd.rememberRegion) { - sif::warning << "StarTrackerHandler::handleChecksumReply: Region mismatch" << std::endl; - return REGION_MISMATCH; - } - if (checksumReply.getAddress() != checksumCmd.rememberAddress) { - sif::warning << "StarTrackerHandler::handleChecksumReply: Address mismatch" << std::endl; - return ADDRESS_MISMATCH; - } - if (checksumReply.getLength() != checksumCmd.rememberLength) { - sif::warning << "StarTrackerHandler::handleChecksumReply: Length mismatch" << std::endl; - return LENGTH_MISSMATCH; - } - PoolReadGuard rg(&checksumSet); - checksumSet.checksum = checksumReply.getChecksum(); - handleDeviceTM(&checksumSet, StarTracker::CHECKSUM); -#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - checksumReply.printChecksum(); -#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::handlePingReply() { - ReturnValue_t result = RETURN_OK; - uint32_t pingId = 0; - const uint8_t* reply = dataLinkLayer.getReply(); - uint8_t status = dataLinkLayer.getStatusField(); - const uint8_t* buffer = reply + ACTION_DATA_OFFSET; - size_t size = sizeof(pingId); - SerializeAdapter::deSerialize(&pingId, &buffer, &size, SerializeIF::Endianness::LITTLE); -#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - sif::info << "StarTracker: Ping status: "<< static_cast(status) << std::endl; - sif::info << "Ping id: 0x"<< std::hex << pingId << std::endl; -#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ - if (status != StarTracker::STATUS_OK || pingId != PING_ID) { - sif::warning << "StarTrackerHandler::handlePingReply: Ping failed" << std::endl; - result = PING_FAILED; - } - else { -#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - sif::info << "StarTracker: Ping successful" << std::endl; -#endif - } - return result; -} - -ReturnValue_t StarTrackerHandler::checkProgram() { - PoolReadGuard pg(&versionSet); - switch(versionSet.program.value) { - case StarTracker::Program::BOOTLOADER: - // Star tracker currently in bootloader program. Need to send boot command to switch to - // firmware program - if (startupState != StartupState::IDLE) { - startupState = StartupState::BOOT; - } - break; - case StarTracker::Program::FIRMWARE: - // Firmware already booted - if (startupState != StartupState::IDLE) { - startupState = StartupState::LIMITS; - } - break; - default: - sif::warning << "StarTrackerHandler::checkProgram: Version set has invalid program ID" - << std::endl; - return INVALID_PROGRAM; - } - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::handleTm(LocalPoolDataSetBase& dataset, size_t size) { - ReturnValue_t result = RETURN_OK; - uint8_t status = *(dataLinkLayer.getReply() + STATUS_OFFSET); - if(status != StarTracker::STATUS_OK) { - sif::warning << "StarTrackerHandler::handleTm: Reply error: " - << static_cast(status) << std::endl; - return REPLY_ERROR; - } - result = dataset.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); - if (result != RETURN_OK) { - return result; - } - const uint8_t* reply = dataLinkLayer.getReply() + TICKS_OFFSET; - dataset.setValidityBufferGeneration(false); - result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::handleTm: Deserialization failed" - << std::endl; - } - dataset.setValidityBufferGeneration(true); - dataset.setValidity(true, true); - result = dataset.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); - if (result != RETURN_OK) { - return result; - } -#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - dataset.printSet(); -#endif - return result; -} - -ReturnValue_t StarTrackerHandler::handleActionReplySet(LocalPoolDataSetBase& dataset, size_t size) { - ReturnValue_t result = RETURN_OK; - uint8_t status = *(dataLinkLayer.getReply() + STATUS_OFFSET); - if(status != StarTracker::STATUS_OK) { - sif::warning << "StarTrackerHandler::handleActionReplySet: Reply error: " - << static_cast(status) << std::endl; - return REPLY_ERROR; - } - result = dataset.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); - if (result != RETURN_OK) { - return result; - } - const uint8_t* reply = dataLinkLayer.getReply() + ACTION_DATA_OFFSET; - dataset.setValidityBufferGeneration(false); - result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::handleActionReplySet Deserialization failed" - << std::endl; - } - dataset.setValidityBufferGeneration(true); - dataset.setValidity(true, true); - result = dataset.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); - if (result != RETURN_OK) { - return result; - } -#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - dataset.printSet(); -#endif - return result; -} - -void StarTrackerHandler::handleStartup(const uint8_t* parameterId) { - switch(*parameterId) { - case (StarTracker::ID::LIMITS): { - startupState = StartupState::TRACKING; - break; - } - case (StarTracker::ID::TRACKING): { - startupState = StartupState::MOUNTING; - break; - } - case (StarTracker::ID::MOUNTING): { - startupState = StartupState::CAMERA; - break; - } - case (StarTracker::ID::CAMERA): { - startupState = StartupState::BLOB; - break; - } - case (StarTracker::ID::BLOB): { - startupState = StartupState::CENTROIDING; - break; - } - case (StarTracker::ID::CENTROIDING): { - startupState = StartupState::LISA; - break; - } - case (StarTracker::ID::LISA): { - startupState = StartupState::MATCHING; - break; - } - case (StarTracker::ID::MATCHING): { - startupState = StartupState::VALIDATION; - break; - } - case (StarTracker::ID::VALIDATION): { - startupState = StartupState::ALGO; - break; - } - case (StarTracker::ID::ALGO): { - startupState = StartupState::DONE; - break; - } - default: { - sif::debug << "StarTrackerHandler::handleStartup: Received parameter reply with unexpected" - << " parameter ID" << std::endl; - break; - } - } -} diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.h b/bsp_q7s/devices/startracker/StarTrackerHandler.h deleted file mode 100644 index 65bd65b8..00000000 --- a/bsp_q7s/devices/startracker/StarTrackerHandler.h +++ /dev/null @@ -1,548 +0,0 @@ -#ifndef MISSION_DEVICES_STARTRACKERHANDLER_H_ -#define MISSION_DEVICES_STARTRACKERHANDLER_H_ - -#include "fsfw/devicehandlers/DeviceHandlerBase.h" -#include "fsfw/src/fsfw/serialize/SerializeAdapter.h" -#include "fsfw/timemanager/Countdown.h" -#include "thirdparty/arcsec_star_tracker/common/SLIP.h" -#include -#include "ArcsecDatalinkLayer.h" -#include "StarTrackerDefinitions.h" -#include "ArcsecJsonParamBase.h" -#include "StrHelper.h" - -/** - * @brief This is the device handler for the star tracker from arcsec. - * - * @details Datasheet: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/ - * Arbeitsdaten/08_Used%20Components/ArcSec_KULeuven_Startracker/ - * Sagitta%201.0%20Datapack&fileid=659181 - * @author J. Meier - */ -class StarTrackerHandler: public DeviceHandlerBase { -public: - - /** - * @brief Constructor - * - * @param objectId - * @param comIF - * @param comCookie - * @param gpioComIF Pointer to gpio communication interface - * @param enablePin GPIO connected to the enable pin of the reaction wheels. Must be pulled - * to high to enable the device. - */ - StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie, - StrHelper* strHelper); - virtual ~StarTrackerHandler(); - - ReturnValue_t initialize() override; - - /** - * @brief Overwrite this function from DHB to handle commands executed by the str image - * loader task. - */ - ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, - const uint8_t* data, size_t size) override; - - void performOperationHook() override; - -protected: - void doStartUp() override; - void doShutDown() override; - void doOffActivity() override; - ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override; - ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) override; - void fillCommandAndReplyMap() override; - ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, - const uint8_t * commandData,size_t commandDataLen) override; - ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize, - DeviceCommandId_t *foundId, size_t *foundLen) override; - ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) override; - void setNormalDatapoolEntriesInvalid() override; - uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; - ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) override; - /** - * @brief Overwritten here to always read all available data from the UartComIF. - */ - virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override; - virtual ReturnValue_t doSendReadHook() override; - -private: - - static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER; - - //! [EXPORT] : [COMMENT] Received reply is too short - static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xB0); - //! [EXPORT] : [COMMENT] Received reply with invalid CRC - static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xB1); - //! [EXPORT] : [COMMENT] Image loader executing - static const ReturnValue_t IMAGE_LOADER_EXECUTING = MAKE_RETURN_CODE(0xB2); - - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER; - - //! [EXPORT] : [COMMENT] Status in temperature reply signals error - static const ReturnValue_t TEMPERATURE_REQ_FAILED = MAKE_RETURN_CODE(0xA0); - //! [EXPORT] : [COMMENT] Ping command failed - static const ReturnValue_t PING_FAILED = MAKE_RETURN_CODE(0xA1); - //! [EXPORT] : [COMMENT] Status in version reply signals error - static const ReturnValue_t VERSION_REQ_FAILED = MAKE_RETURN_CODE(0xA3); - //! [EXPORT] : [COMMENT] Status in interface reply signals error - static const ReturnValue_t INTERFACE_REQ_FAILED = MAKE_RETURN_CODE(0xA4); - //! [EXPORT] : [COMMENT] Status in power reply signals error - static const ReturnValue_t POWER_REQ_FAILED = MAKE_RETURN_CODE(0xA5); - //! [EXPORT] : [COMMENT] Status of reply to parameter set command signals error - static const ReturnValue_t SET_PARAM_FAILED = MAKE_RETURN_CODE(0xA6); - //! [EXPORT] : [COMMENT] Status of reply to action command signals error - static const ReturnValue_t ACTION_FAILED = MAKE_RETURN_CODE(0xA7); - //! [EXPORT] : [COMMENT] Received upload image command with invalid length - static const ReturnValue_t UPLOAD_TOO_SHORT = MAKE_RETURN_CODE(0xA8); - //! [EXPORT] : [COMMENT] Received upload image command with invalid position field - static const ReturnValue_t UPLOAD_INVALID_POSITION = MAKE_RETURN_CODE(0xA8); - //! [EXPORT] : [COMMENT] Position value in upload image reply not matching sent position - static const ReturnValue_t UPLOAD_IMAGE_FAILED = MAKE_RETURN_CODE(0xA9); - //! [EXPORT] : [COMMENT] Received upload image command with invalid length - static const ReturnValue_t INVALID_UPLOAD_COMMAND = MAKE_RETURN_CODE(0xAA); - //! [EXPORT] : [COMMENT] Received invalid path string. Exceeds allowed length - static const ReturnValue_t FILE_PATH_TOO_LONG = MAKE_RETURN_CODE(0xAB); - //! [EXPORT] : [COMMENT] Name of file received with command is too long - static const ReturnValue_t FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xAC); - //! [EXPORT] : [COMMENT] Received version reply with invalid program ID - static const ReturnValue_t INVALID_PROGRAM = MAKE_RETURN_CODE(0xAD); - //! [EXPORT] : [COMMENT] Status field reply signals error - static const ReturnValue_t REPLY_ERROR = MAKE_RETURN_CODE(0xAE); - //! [EXPORT] : [COMMENT] Status field of contrast reply signals error - static const ReturnValue_t CONTRAST_REQ_FAILED = MAKE_RETURN_CODE(0xAE); - //! [EXPORT] : [COMMENT] Received command which is too short (some data is missing for proper execution) - static const ReturnValue_t COMMAND_TOO_SHORT = MAKE_RETURN_CODE(0xAF); - //! [EXPORT] : [COMMENT] Received command with invalid length (too few or too many parameters) - static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xB0); - //! [EXPORT] : [COMMENT] Region mismatch between send and received data - static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(0xB1); - //! [EXPORT] : [COMMENT] Address mismatch between send and received data - static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(0xB2); - //! [EXPORT] : [COMMENT] Length field mismatch between send and received data - static const ReturnValue_t lENGTH_MISMATCH = MAKE_RETURN_CODE(0xB3); - //! [EXPORT] : [COMMENT] Specified file does not exist - static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xB4); - //! [EXPORT] : [COMMENT] Reply to upload centroid does not match commanded centroid id - static const ReturnValue_t UPLOAD_CENTROID_ID_MISMATCH = MAKE_RETURN_CODE(0xB5); - //! [EXPORT] : [COMMENT] Download blob pixel command has invalid type field - static const ReturnValue_t INVALID_TYPE = MAKE_RETURN_CODE(0xB6); - //! [EXPORT] : [COMMENT] Received FPGA action command with invalid ID - static const ReturnValue_t INVALID_ID = MAKE_RETURN_CODE(0xB7); - - static const size_t MAX_PATH_SIZE = 50; - static const size_t MAX_FILE_NAME = 30; - - // position (uint32) + 1024 image data - static const size_t UPLOAD_COMMAND_LEN = 1028; - // Max valid position value in upload image command - static const uint16_t MAX_POSITION= 4095; - static const uint8_t STATUS_OFFSET = 1; - static const uint8_t TICKS_OFFSET = 2; - static const uint8_t TIME_OFFSET = 6; - static const uint8_t TM_DATA_FIELD_OFFSET = 14; - static const uint8_t PARAMETER_ID_OFFSET = 0; - static const uint8_t ACTION_ID_OFFSET = 0; - static const uint8_t ACTION_DATA_OFFSET = 2; - // Ping request will reply ping with this ID (data field) - static const uint32_t PING_ID = 0x55; - static const uint32_t BOOT_REGION_ID = 1; - static const MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING; - static const uint32_t MUTEX_TIMEOUT = 20; - static const uint32_t BOOT_TIMEOUT = 1000; - - class WriteCmd { - public: - static const uint8_t ADDRESS_OFFSET = 1; - static const uint8_t FILE_OFFSET = 5; - // Minimum length of a write command (region, address and filename) - static const size_t MIN_LENGTH = 7; - }; - - class ReadCmd { - public: - static const uint8_t ADDRESS_OFFSET = 1; - static const uint8_t LENGTH_OFFSET = 5; - static const uint8_t FILE_OFFSET = 9; - // Minimum length of a read command (region, address, length and filename) - static const size_t MIN_LENGTH = 11; - }; - - class EraseCmd { - public: - static const uint8_t LENGTH = 1; - uint8_t rememberRegion = 0; - }; - - EraseCmd eraseCmd; - - class UnlockCmd { - public: - static const uint8_t CODE_OFFSET = 1; - }; - - class ChecksumCmd { - public: - static const uint8_t ADDRESS_OFFSET = 1; - static const uint8_t LENGTH_OFFSET = 5; - // Length of checksum command - static const size_t LENGTH = 9; - uint8_t rememberRegion = 0; - uint32_t rememberAddress = 0; - uint32_t rememberLength = 0; - }; - - ChecksumCmd checksumCmd; - - class SetTimeCmd { - public: - static const uint8_t LENGTH = 8; - }; - - class DownloadCentroidCmd { - public: - static const uint8_t LENGTH = 1; - }; - - class UploadCentroid { - public: - uint8_t rememberId = 0; - }; - - UploadCentroid uploadCentroid; - - class DownloadMatchedStarCmd { - public: - static const uint8_t LENGTH = 1; - }; - - class DownloadDbImageCmd { - public: - static const uint8_t LENGTH = 1; - }; - - class DownloadBlobPixCmd { - public: - static const uint8_t LENGTH = 2; - static const uint8_t NORMAL = 0; - static const uint8_t FAST = 1; - }; - - class FpgaDownloadCmd { - public: - static const uint8_t MIN_LENGTH = 10; - }; - - class FpgaActionCmd { - public: - static const uint8_t LENGTH = 1; - static const uint8_t ID = 3; - }; - - MessageQueueIF* eventQueue = nullptr; - - ArcsecDatalinkLayer dataLinkLayer; - - StarTracker::TemperatureSet temperatureSet; - StarTracker::VersionSet versionSet; - StarTracker::PowerSet powerSet; - StarTracker::InterfaceSet interfaceSet; - StarTracker::TimeSet timeSet; - StarTracker::SolutionSet solutionSet; - StarTracker::HistogramSet histogramSet; - StarTracker::ContrastSet contrastSet; - StarTracker::ChecksumSet checksumSet; - StarTracker::DownloadCentroidSet downloadCentroidSet; - StarTracker::DownloadMatchedStar downloadMatchedStar; - StarTracker::DownloadDBImage downloadDbImage; - StarTracker::DownloadBlobPixel downloadBlobPixel; - - // Pointer to object responsible for uploading and downloading images to/from the star tracker - StrHelper* strHelper = nullptr; - - uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; - - // Countdown to insert delay for star tracker to switch from bootloader to firmware program - Countdown bootCountdown; - - std::string paramJsonFile = "/mnt/sd0/startracker/full.json"; - - enum class InternalState { - TEMPERATURE_REQUEST - }; - - InternalState internalState = InternalState::TEMPERATURE_REQUEST; - - enum class StartupState { - IDLE, - CHECK_BOOT_STATE, - BOOT, - BOOT_DELAY, - LIMITS, - TRACKING, - MOUNTING, - CAMERA, - BLOB, - CENTROIDING, - LISA, - MATCHING, - VALIDATION, - ALGO, - WAIT_FOR_EXECUTION, - DONE - }; - - StartupState startupState = StartupState::IDLE; - - bool strHelperExecuting = false; - - /** - * @brief Handles internal state - */ - void handleInternalState(); - - /** - * @brief Checks mode for commands requiring MODE_ON of MODE_NORMAL for execution. - * - * @param actionId Action id of command to execute - */ - ReturnValue_t checkMode(ActionId_t actionId); - - /** - * @brief This function initializes the serial link ip protocol struct slipInfo. - */ - void slipInit(); - - ReturnValue_t scanForActionReply(DeviceCommandId_t *foundId); - ReturnValue_t scanForParameterReply(DeviceCommandId_t *foundId); - ReturnValue_t scanForTmReply(DeviceCommandId_t *foundId); - - /** - * @brief Fills command buffer with data to ping the star tracker - */ - void preparePingRequest(); - - /** - * @brief Fills command buffer with data to request the time telemetry. - */ - void prepareTimeRequest(); - - /** - * @brief Handles all received event messages - */ - void handleEvent(EventMessage* eventMessage); - - /** - * @brief Executes the write command - * - * @param commandData Pointer to received command data - * @param commandDataLen Size of received command data - * - * @return RETURN_OK if start of execution was successful, otherwise error return value - */ - ReturnValue_t executeWriteCommand(const uint8_t* commandData, size_t commandDataLen); - - /** - * @brief Starts the execution of the fpga download command - * - * @param commandData Pointer to buffer with command data - * @param commandDataLen Size of received command - */ - ReturnValue_t executeFpgaDownloadCommand(const uint8_t* commandData, size_t commandDataLen); - - /** - * @brief Extracts information for flash-read-command from TC data and starts execution of - * flash-read-procedure - * - * @param commandData Pointer to received command data - * @param commandDataLen Size of received command data - * - * @return RETURN_OK if start of execution was successful, otherwise error return value - */ - ReturnValue_t executeReadCommand(const uint8_t* commandData, size_t commandDataLen); - - /** - * @brief Fills command buffer with data to boot image (works only when star tracker is - * in bootloader mode). - */ - void prepareBootCommand(); - - /** - * @brief Fills command buffer with command to erase a flash region - */ - ReturnValue_t prepareEraseCommand(const uint8_t* commandData, size_t commandDataLen); - - /** - * @brief Fills command buffer with command to unlock flash region - */ - ReturnValue_t prepareUnlockCommand(const uint8_t* commandData, size_t commandDataLen); - - /** - * @brief Fills command buffer with command to get the checksum of a flash part - */ - ReturnValue_t prepareChecksumCommand(const uint8_t* commandData, size_t commandDataLen); - - /** - * @brief Fills command buffer with command to set the unix time - */ - ReturnValue_t prepareSetTimeCommand(const uint8_t* commandData, size_t commandDataLen); - - /** - * @brief Fills command buffer with command to request a centroid - */ - ReturnValue_t prepareDownloadCentroidCommand(const uint8_t* commandData, size_t commandDataLen); - - /** - * @brief Fills command buffer with command to upload a centroid for testing purpose - */ - ReturnValue_t prepareUploadCentroidCommand(const uint8_t* commandData, size_t commandDataLen); - - /** - * @brief Fills the command buffer with the command to take an image. - */ - void prepareTakeImageCommand(const uint8_t* commandData); - - /** - * @brief Fills command buffer with data to request the version telemetry packet - */ - void prepareVersionRequest(); - - /** - * @brief Fills the command buffer with data to request the interface telemetry packet. - */ - void prepareInterfaceRequest(); - - /** - * @brief Fills the command buffer with data to request the power telemetry packet. - */ - void preparePowerRequest(); - - /** - * @brief Fills command buffer with data to reboot star tracker. - */ - void prepareRebootCommand(); - - /** - * @brief Fills command buffer with data to subscribe to a telemetry packet. - * - * @param tmId The ID of the telemetry packet to subscribe to - */ - void prepareSubscriptionCommand(const uint8_t* tmId); - - /** - * @brief Fills command buffer with data to request solution telemtry packet (contains - * attitude information) - */ - void prepareSolutionRequest(); - - /** - * @brief Fills command buffer with data to request temperature from star tracker - */ - void prepareTemperatureRequest(); - - /** - * @brief Fills command buffer with data to request histogram - */ - void prepareHistogramRequest(); - - void prepareContrastRequest(); - - /** - * @brief Fills command buffer with command to reset the error signal of the star tracker - */ - void prepareErrorResetRequest(); - - /** - * @brief Reads parameters from json file specified by string in commandData and - * prepares the command to apply the parameter set to the star tracker - * - * @param commandData Contains string with file name - * @param commandDataLen Length of command - * @param paramSet The object defining the command generation - * - * @return RETURN_OK if successful, otherwise error return Value - */ - ReturnValue_t prepareParamCommand(const uint8_t* commandData, size_t commandDataLen, - ArcsecJsonParamBase& paramSet); - - /** - * @brief Fills command buffer with data to request matched star. - */ - ReturnValue_t prepareDownloadMatchedStarCommand(const uint8_t* commandData, - size_t commandDataLen); - - /** - * @brief Fills command buffer with data to request matched star coordinates. - */ - ReturnValue_t prepareDownloadDbImageCommand(const uint8_t* commandData, - size_t commandDataLen); - - /** - * @brief Fills command buffer with data to request output of the blob filter algorithm. - */ - ReturnValue_t prepareDownloadBlobPixelCommand(const uint8_t* commandData, - size_t commandDataLen); - - /** - * @brief With this command the FPGA update will be applied to the star tracker - */ - ReturnValue_t prepareFpgaActionCommand(const uint8_t* commandData, size_t commandDataLen); - - /** - * @brief Handles action replies with datasets. - */ - ReturnValue_t handleActionReplySet(LocalPoolDataSetBase& dataset, size_t size); - - /** - * @brief Default function to handle action replies - */ - ReturnValue_t handleActionReply(); - - /** - * @brief Handles reply to upload centroid command - */ - ReturnValue_t handleUploadCentroidReply(); - - /** - * @brief Handles reply to erase command - */ - ReturnValue_t handleEraseReply(); - - /** - * @brief Handles reply to checksum command - */ - ReturnValue_t handleChecksumReply(); - - /** - * @brief Handles all set parameter replies - */ - ReturnValue_t handleSetParamReply(); - - ReturnValue_t handlePingReply(); - - /** - * @brief Checks the loaded program by means of the version set - */ - ReturnValue_t checkProgram(); - - /** - * @brief Handles the startup state machine - */ - void handleStartup(const uint8_t* parameterId); - - /** - * @brief Handles telemtry replies and fills the appropriate dataset - * - * @param dataset Dataset where reply data will be written to - * @param size Size of the dataset - * - * @return RETURN_OK if successful, otherwise error return value - */ - ReturnValue_t handleTm(LocalPoolDataSetBase& dataset, size_t size); -}; - -#endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */ diff --git a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp deleted file mode 100644 index 9c33e1c9..00000000 --- a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp +++ /dev/null @@ -1,716 +0,0 @@ -#include "StarTrackerJsonCommands.h" -#include "ArcsecJsonKeys.h" - -Limits::Limits() : ArcsecJsonParamBase(arcseckeys::LIMITS) {} - -size_t Limits::getSize() { - return COMMAND_SIZE; -} - -ReturnValue_t Limits::createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::LIMITS); - offset = 2; - result = getParam(arcseckeys::ACTION, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::FPGA18CURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::FPGA25CURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::FPGA10CURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::MCUCURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::CMOS21CURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::CMOSPIXCURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::CMOS33CURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::CMOSVRESCURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::CMOS_TEMPERATURE, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::MCU_TEMPERATURE, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - return RETURN_OK; -} - - -Tracking::Tracking() : ArcsecJsonParamBase(arcseckeys::TRACKING) {} - -size_t Tracking::getSize() { - return COMMAND_SIZE; -} - -ReturnValue_t Tracking::createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::TRACKING); - offset = 2; - result = getParam(arcseckeys::THIN_LIMIT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::OUTLIER_THRESHOLD, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::OUTLIER_THRESHOLD_QUEST, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::TRACKER_CHOICE, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - return RETURN_OK; -} - - -Mounting::Mounting() : ArcsecJsonParamBase(arcseckeys::MOUNTING) {} - -size_t Mounting::getSize() { - return COMMAND_SIZE; -} - -ReturnValue_t Mounting::createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::MOUNTING); - offset = 2; - result = getParam(arcseckeys::qw, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::qx, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::qy, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::qz, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - return RETURN_OK; -} - - -Camera::Camera() : ArcsecJsonParamBase(arcseckeys::CAMERA) {} - -size_t Camera::getSize() { - return COMMAND_SIZE; -} - -ReturnValue_t Camera::createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::CAMERA); - offset = 2; - result = getParam(arcseckeys::MODE, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::FOCALLENGTH, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::EXPOSURE, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::INTERVAL, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::OFFSET, param); - if (result != RETURN_OK) { - return result; - } - addint16(param, buffer + offset); - offset += sizeof(int16_t); - result = getParam(arcseckeys::PGAGAIN, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::ADCGAIN, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::REG_1, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::VAL_1, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::REG_2, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::VAL_2, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::REG_3, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::VAL_3, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::REG_4, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::VAL_4, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::REG_5, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::VAL_5, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::REG_6, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::VAL_6, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::REG_7, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::VAL_7, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::REG_8, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::VAL_8, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::FREQ_1, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::FREQ_2, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - return RETURN_OK; -} - - -Blob::Blob() : ArcsecJsonParamBase(arcseckeys::BLOB) {} - -size_t Blob::getSize() { - return COMMAND_SIZE; -} - -ReturnValue_t Blob::createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::BLOB); - offset = 2; - result = getParam(arcseckeys::MODE, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::MIN_VALUE, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::MIN_DISTANCE, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::NEIGHBOUR_DISTANCE, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::NEIGHBOUR_BRIGHT_PIXELS, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::MIN_TOTAL_VALUE, param); - if (result != RETURN_OK) { - return result; - } - adduint16(param, buffer + offset); - offset += sizeof(uint16_t); - result = getParam(arcseckeys::MAX_TOTAL_VALUE, param); - if (result != RETURN_OK) { - return result; - } - adduint16(param, buffer + offset); - offset += sizeof(uint16_t); - result = getParam(arcseckeys::MIN_BRIGHT_NEIGHBOURS, param); - if (result != RETURN_OK) { - return result; - } - adduint16(param, buffer + offset); - offset += sizeof(uint16_t); - result = getParam(arcseckeys::MAX_BRIGHT_NEIGHBOURS, param); - if (result != RETURN_OK) { - return result; - } - adduint16(param, buffer + offset); - offset += sizeof(uint16_t); - result = getParam(arcseckeys::MAX_PIXEL_TO_CONSIDER, param); - if (result != RETURN_OK) { - return result; - } - adduint32(param, buffer + offset); - offset += sizeof(uint32_t); - result = getParam(arcseckeys::SIGNAL_THRESHOLD, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::DARK_THRESHOLD, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::ENABLE_HISTOGRAM, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::ENABLE_CONTRAST, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::BIN_MODE, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - return RETURN_OK; -} - - -Centroiding::Centroiding() : ArcsecJsonParamBase(arcseckeys::CENTROIDING) {} - -size_t Centroiding::getSize() { - return COMMAND_SIZE; -} - -ReturnValue_t Centroiding::createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::CENTROIDING); - offset = 2; - result = getParam(arcseckeys::ENABLE_FILTER, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::MAX_QUALITY, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::MIN_QUALITY, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::MAX_INTENSITY, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::MIN_INTENSITY, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::MAX_MAGNITUDE, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::GAUSSIAN_CMAX, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::GAUSSIAN_CMIN, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::TRANSMATRIX_00, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::TRANSMATRIX_01, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::TRANSMATRIX_10, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::TRANSMATRIX_11, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - return RETURN_OK; -} - - -Lisa::Lisa() : ArcsecJsonParamBase(arcseckeys::LISA) {} - -size_t Lisa::getSize() { - return COMMAND_SIZE; -} - -ReturnValue_t Lisa::createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::LISA); - offset = 2; - result = getParam(arcseckeys::PREFILTER_DIST_THRESHOLD, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::PREFILTER_ANGLE_THRESHOLD, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::FOV_WIDTH, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::FOV_HEIGHT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::FLOAT_STAR_LIMIT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::CLOSE_STAR_LIMIT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::RATING_WEIGHT_CLOSE_STAR_COUNT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::RATING_WEIGHT_FRACTION_CLOSE, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::RATING_WEIGHT_DB_STAR_COUNT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::MAX_COMBINATIONS, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::NR_STARS_STOP, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::FRACTION_CLOSE_STOP, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - return RETURN_OK; -} - - -Matching::Matching() : ArcsecJsonParamBase(arcseckeys::MATCHING) {} - -size_t Matching::getSize() { - return COMMAND_SIZE; -} - -ReturnValue_t Matching::createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::MATCHING); - offset = 2; - result = getParam(arcseckeys::SQUARED_DISTANCE_LIMIT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::SQUARED_SHIFT_LIMIT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - return RETURN_OK; -} - - -Validation::Validation() : ArcsecJsonParamBase(arcseckeys::VALIDATION) {} - -size_t Validation::getSize() { - return COMMAND_SIZE; -} - -ReturnValue_t Validation::createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::VALIDATION); - offset = 2; - result = getParam(arcseckeys::STABLE_COUNT, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::MAX_DIFFERENCE, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::MIN_TRACKER_CONFIDENCE, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::MIN_MATCHED_STARS, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - return RETURN_OK; -} - -Algo::Algo() : ArcsecJsonParamBase(arcseckeys::ALGO) {} - -size_t Algo::getSize() { - return COMMAND_SIZE; -} - -ReturnValue_t Algo::createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::ALGO); - offset = 2; - result = getParam(arcseckeys::MODE, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::L2T_MIN_CONFIDENCE, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::L2T_MIN_MATCHED, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::T2L_MIN_CONFIDENCE, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::T2L_MIN_MATCHED, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - return RETURN_OK; -} diff --git a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h deleted file mode 100644 index 868c18ea..00000000 --- a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h +++ /dev/null @@ -1,215 +0,0 @@ -#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ -#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ - -/** - * @brief This file defines a few helper classes to generate commands by means of the parameters - * defined in the arcsec json files. - * @author J. Meier - */ - -#include - -#include "fsfw/serviceinterface/ServiceInterface.h" -#include "ArcsecJsonParamBase.h" - - -/** - * @brief Generates command to set the limit parameters - * - */ -class Limits : public ArcsecJsonParamBase { -public: - - Limits(); - - size_t getSize(); - -private: - - static const size_t COMMAND_SIZE = 43; - - virtual ReturnValue_t createCommand(uint8_t* buffer) override; -}; - - -/** - * @brief Generates the command to configure the tracking algorithm. - * - */ -class Tracking : public ArcsecJsonParamBase { -public: - - Tracking(); - - size_t getSize(); - -private: - - static const size_t COMMAND_SIZE = 15; - - ReturnValue_t createCommand(uint8_t* buffer) override; - -}; - - -/** - * @brief Generates the command to set the mounting quaternion - * - */ -class Mounting : public ArcsecJsonParamBase { -public: - - Mounting(); - - size_t getSize(); - -private: - - static const size_t COMMAND_SIZE = 18; - - ReturnValue_t createCommand(uint8_t* buffer) override; - -}; - - -/** - * @brief Generates the command to set the mounting quaternion - * - */ -class Camera : public ArcsecJsonParamBase { -public: - - Camera(); - - size_t getSize(); - -private: - - static const size_t COMMAND_SIZE = 43; - - ReturnValue_t createCommand(uint8_t* buffer) override; - -}; - - -/** - * @brief Generates the command to configure the blob algorithm - * - */ -class Blob : public ArcsecJsonParamBase { -public: - - Blob(); - - size_t getSize(); - -private: - - static const size_t COMMAND_SIZE = 24; - - ReturnValue_t createCommand(uint8_t* buffer) override; - -}; - - -/** - * @brief Generates the command to configure the centroiding algorithm - * - */ -class Centroiding : public ArcsecJsonParamBase { -public: - - Centroiding(); - - size_t getSize(); - -private: - - static const size_t COMMAND_SIZE = 47; - - ReturnValue_t createCommand(uint8_t* buffer) override; - -}; - - -/** - * @brief Generates the command to configure the LISA (lost in space algorithm) - * - */ -class Lisa : public ArcsecJsonParamBase { -public: - - Lisa(); - - size_t getSize(); - -private: - - static const size_t COMMAND_SIZE = 48; - - ReturnValue_t createCommand(uint8_t* buffer) override; - -}; - - -/** - * @brief Generates the command to configure the matching algorithm - * - */ -class Matching : public ArcsecJsonParamBase { -public: - - Matching(); - - size_t getSize(); - -private: - - static const size_t COMMAND_SIZE = 10; - - ReturnValue_t createCommand(uint8_t* buffer) override; - -}; - - -/** - * @brief Generates the command to configure the validation parameters - * - */ -class Validation : public ArcsecJsonParamBase { -public: - - Validation(); - - size_t getSize(); - -private: - - static const size_t COMMAND_SIZE = 12; - - ReturnValue_t createCommand(uint8_t* buffer) override; - -}; - - -/** - * @brief Generates command to configure the mechanism of automatically switching between the - * LISA and other algorithms. - * - */ -class Algo : public ArcsecJsonParamBase { -public: - - Algo(); - - size_t getSize(); - -private: - - static const size_t COMMAND_SIZE = 13; - - ReturnValue_t createCommand(uint8_t* buffer) override; - -}; - -#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ */ diff --git a/bsp_q7s/devices/startracker/StrHelper.cpp b/bsp_q7s/devices/startracker/StrHelper.cpp deleted file mode 100644 index 0be38ad7..00000000 --- a/bsp_q7s/devices/startracker/StrHelper.cpp +++ /dev/null @@ -1,702 +0,0 @@ -#include "StrHelper.h" - -#include "mission/utility/Timestamp.h" - -#include -#include - -StrHelper::StrHelper(object_id_t objectId) : SystemObject(objectId){ - -} - -StrHelper::~StrHelper() { -} - -ReturnValue_t StrHelper::initialize() { - sdcMan = SdCardManager::instance(); - if (sdcMan == nullptr) { - sif::warning << "StrHelper::initialize: Invalid SD Card Manager" << std::endl; - return RETURN_FAILED; - } - return RETURN_OK; -} - -ReturnValue_t StrHelper::performOperation(uint8_t operationCode) { - ReturnValue_t result = RETURN_OK; - semaphore.acquire(); - while(true) { - switch(internalState) { - case InternalState::IDLE: { - semaphore.acquire(); - break; - } - case InternalState::UPLOAD_IMAGE: { - result = performImageUpload(); - if (result == RETURN_OK){ - triggerEvent(IMAGE_UPLOAD_SUCCESSFUL); - } - else { - triggerEvent(IMAGE_UPLOAD_FAILED); - } - internalState = InternalState::IDLE; - break; - } - case InternalState::DOWNLOAD_IMAGE: { - result = performImageDownload(); - if (result == RETURN_OK){ - triggerEvent(IMAGE_DOWNLOAD_SUCCESSFUL); - } - else { - triggerEvent(IMAGE_DOWNLOAD_FAILED); - } - internalState = InternalState::IDLE; - break; - } - case InternalState::FLASH_WRITE: { - result = performFlashWrite(); - if (result == RETURN_OK){ - triggerEvent(FLASH_WRITE_SUCCESSFUL); - } - else { - triggerEvent(FLASH_WRITE_FAILED); - } - internalState = InternalState::IDLE; - break; - } - case InternalState::FLASH_READ: { - result = performFlashRead(); - if (result == RETURN_OK){ - triggerEvent(FLASH_READ_SUCCESSFUL); - } - else { - triggerEvent(FLASH_READ_FAILED); - } - internalState = InternalState::IDLE; - break; - } - case InternalState::DOWNLOAD_FPGA_IMAGE: { - result = performFpgaDownload(); - if (result == RETURN_OK){ - triggerEvent(FPGA_DOWNLOAD_SUCCESSFUL); - } - else { - triggerEvent(FPGA_DOWNLOAD_FAILED); - } - internalState = InternalState::IDLE; - break; - } - case InternalState::UPLOAD_FPGA_IMAGE: { - result = performFpgaUpload(); - if (result == RETURN_OK){ - triggerEvent(FPGA_UPLOAD_SUCCESSFUL); - } - else { - triggerEvent(FPGA_UPLOAD_FAILED); - } - internalState = InternalState::IDLE; - break; - } - default: - sif::debug << "StrHelper::performOperation: Invalid state" << std::endl; - break; - } - } -} - -ReturnValue_t StrHelper::setComIF(DeviceCommunicationIF* communicationInterface_) { - uartComIF = dynamic_cast(communicationInterface_); - if (uartComIF == nullptr) { - sif::warning << "StrHelper::initialize: Invalid uart com if" << std::endl; - return RETURN_FAILED; - } - return RETURN_OK; -} - -void StrHelper::setComCookie(CookieIF* comCookie_) { - comCookie = comCookie_; -} - -ReturnValue_t StrHelper::startImageUpload(std::string fullname) { - ReturnValue_t result = checkPath(fullname); - if (result != RETURN_OK) { - return result; - } - uploadImage.uploadFile = fullname; - if(not std::filesystem::exists(fullname)) { - return FILE_NOT_EXISTS; - } - internalState = InternalState::UPLOAD_FPGA_IMAGE; - semaphore.release(); - terminate = false; - return RETURN_OK; -} - -ReturnValue_t StrHelper::startImageDownload(std::string path) { - ReturnValue_t result = checkPath(path); - if (result != RETURN_OK) { - return result; - } - if(not std::filesystem::exists(path)) { - return PATH_NOT_EXISTS; - } - downloadImage.path = path; - internalState = InternalState::DOWNLOAD_IMAGE; - terminate = false; - semaphore.release(); - return RETURN_OK; -} - -void StrHelper::stopProcess() { - terminate = true; -} - -void StrHelper::setDownloadImageName(std::string filename) { - downloadImage.filename = filename; -} - -void StrHelper::setFlashReadFilename(std::string filename) { - flashRead.filename = filename; -} - -void StrHelper::setDownloadFpgaImage(std::string filename) { - fpgaDownload.fileName = filename; -} - -ReturnValue_t StrHelper::startFlashWrite(std::string fullname, uint8_t region, - uint32_t address) { - ReturnValue_t result = checkPath(fullname); - if (result != RETURN_OK) { - return result; - } - flashWrite.fullname = fullname; - if(not std::filesystem::exists(flashWrite.fullname)) { - return FILE_NOT_EXISTS; - } - flashWrite.address = address; - flashWrite.region = region; - internalState = InternalState::FLASH_WRITE; - semaphore.release(); - terminate = false; - return RETURN_OK; -} - -ReturnValue_t StrHelper::startFlashRead(std::string path, uint8_t region, - uint32_t address, uint32_t length) { - ReturnValue_t result = checkPath(path); - if (result != RETURN_OK) { - return result; - } - flashRead.path = path; - if(not std::filesystem::exists(flashRead.path)) { - return FILE_NOT_EXISTS; - } - flashRead.address = address; - flashRead.region = region; - flashRead.size = length; - internalState = InternalState::FLASH_READ; - semaphore.release(); - terminate = false; - return RETURN_OK; -} - -ReturnValue_t StrHelper::startFpgaDownload(std::string path, uint32_t startPosition, - uint32_t length) { - fpgaDownload.path = path; - fpgaDownload.startPosition = startPosition; - fpgaDownload.length = length; - internalState = InternalState::DOWNLOAD_FPGA_IMAGE; - semaphore.release(); - terminate = false; - return RETURN_OK; -} - -ReturnValue_t StrHelper::startFpgaUpload(std::string uploadFile) { - fpgaUpload.uploadFile = uploadFile; - internalState = InternalState::UPLOAD_FPGA_IMAGE; - semaphore.release(); - terminate = false; - return RETURN_OK; -} - -ReturnValue_t StrHelper::performImageDownload() { - ReturnValue_t result; - struct DownloadActionRequest downloadReq; - uint32_t size = 0; - uint32_t retries = 0; - Timestamp timestamp; - std::string image = downloadImage.path + "/" + timestamp.str() + downloadImage.filename ; - std::ofstream file(image, std::ios_base::app | std::ios_base::out); - if(not std::filesystem::exists(image)) { - return FILE_CREATION_FAILED; - } - downloadReq.position = 0; - while(downloadReq.position < ImageDownload::LAST_POSITION) { - if (terminate) { - return RETURN_OK; - } - arc_pack_download_action_req(&downloadReq, commandBuffer, &size); - result = sendAndRead(size, downloadReq.position); - if (result != RETURN_OK) { - if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { - uartComIF->flushUartRxBuffer(comCookie); - retries++; - continue; - } - file.close(); - return result; - } - result = checkActionReply(); - if (result != RETURN_OK) { - if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { - uartComIF->flushUartRxBuffer(comCookie); - retries++; - continue; - } - file.close(); - return result; - } - result = checkReplyPosition(downloadReq.position); - if (result != RETURN_OK) { - if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { - uartComIF->flushUartRxBuffer(comCookie); - retries++; - continue; - } - file.close(); - return result; - } - file.write(reinterpret_cast(datalinkLayer.getReply() + IMAGE_DATA_OFFSET), - IMAGE_DATA_SIZE); - downloadReq.position++; - retries = 0; - } - file.close(); - return RETURN_OK; -} - -ReturnValue_t StrHelper::performImageUpload() { - ReturnValue_t result = RETURN_OK; - uint32_t size = 0; - uint32_t imageSize = 0; - struct UploadActionRequest uploadReq; - uploadReq.position = 0; - std::memset(&uploadReq.data, 0, sizeof(uploadReq.data)); - if (not std::filesystem::exists(uploadImage.uploadFile)) { - triggerEvent(STR_HELPER_FILE_NOT_EXISTS, static_cast(internalState)); - internalState = InternalState::IDLE; - return RETURN_FAILED; - } - std::ifstream file(uploadImage.uploadFile, std::ifstream::binary); - // Set position of next character to end of file input stream - file.seekg(0, file.end); - // tellg returns position of character in input stream - imageSize = file.tellg(); - while((uploadReq.position + 1) * SIZE_IMAGE_PART < imageSize) { - if (terminate) { - return RETURN_OK; - } - file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg); - file.read(reinterpret_cast(uploadReq.data), SIZE_IMAGE_PART); - arc_pack_upload_action_req(&uploadReq, commandBuffer, &size); - result = sendAndRead(size, uploadReq.position); - if (result != RETURN_OK) { - return RETURN_FAILED; - } - result = checkActionReply(); - if (result != RETURN_OK) { - return result; - } - uploadReq.position++; - } - std::memset(uploadReq.data, 0, sizeof(uploadReq.data)); - uint32_t remainder = imageSize - uploadReq.position * SIZE_IMAGE_PART; - file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg); - file.read(reinterpret_cast(uploadReq.data), remainder); - file.close(); - uploadReq.position++; - arc_pack_upload_action_req(&uploadReq, commandBuffer, &size); - result = sendAndRead(size, uploadReq.position); - if (result != RETURN_OK) { - return RETURN_FAILED; - } - result = checkActionReply(); - if (result != RETURN_OK) { - return result; - } - return RETURN_OK; -} - -ReturnValue_t StrHelper::performFlashWrite() { - ReturnValue_t result = RETURN_OK; - uint32_t size = 0; - uint32_t remainingBytes = 0; - uint32_t fileSize = 0; - struct WriteActionRequest req; - if (not std::filesystem::exists(flashWrite.fullname)) { - triggerEvent(STR_HELPER_FILE_NOT_EXISTS, static_cast(internalState)); - internalState = InternalState::IDLE; - return RETURN_FAILED; - } - std::ifstream file(flashWrite.fullname, std::ifstream::binary); - file.seekg(0, file.end); - fileSize = file.tellg(); - remainingBytes = fileSize; - req.region = flashWrite.region; - req.address = flashWrite.address; - req.length = MAX_FLASH_DATA; - while(remainingBytes >= MAX_FLASH_DATA) { - if (terminate) { - return RETURN_OK; - } - file.seekg(fileSize - remainingBytes, file.beg); - file.read(reinterpret_cast(req.data), MAX_FLASH_DATA); - arc_pack_write_action_req(&req, commandBuffer, &size); - result = sendAndRead(size, req.address); - if (result != RETURN_OK) { - return RETURN_FAILED; - } - result = checkFlashActionReply(req.region, req.address, req.length); - if (result != RETURN_OK) { - return result; - } - remainingBytes = remainingBytes - MAX_FLASH_DATA; - } - file.seekg(fileSize - remainingBytes, file.beg); - file.read(reinterpret_cast(req.data), remainingBytes); - file.close(); - arc_pack_write_action_req(&req, commandBuffer, &size); - result = sendAndRead(size, req.address); - if (result != RETURN_OK) { - return RETURN_FAILED; - } - result = checkFlashActionReply(req.region, req.address, req.length); - if (result != RETURN_OK) { - return result; - } - return RETURN_OK; -} - -ReturnValue_t StrHelper::performFlashRead() { - ReturnValue_t result; - struct ReadActionRequest req; - uint32_t bytesRead = 0; - uint32_t size = 0; - uint32_t retries = 0; - Timestamp timestamp; - std::string fullname = flashRead.path + "/" + timestamp.str() + flashRead.filename ; - std::ofstream file(fullname, std::ios_base::app | std::ios_base::out); - if (not std::filesystem::exists(fullname)) { - return FILE_CREATION_FAILED; - } - req.region = flashRead.region; - while(bytesRead < flashRead.size) { - if (terminate) { - return RETURN_OK; - } - if ((flashRead.size - bytesRead) < MAX_FLASH_DATA) { - req.length = flashRead.size - bytesRead; - } - else { - req.length = MAX_FLASH_DATA; - } - req.address = flashRead.address + bytesRead; - arc_pack_read_action_req(&req, commandBuffer, &size); - result = sendAndRead(size, req.address); - if (result != RETURN_OK) { - if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { - uartComIF->flushUartRxBuffer(comCookie); - retries++; - continue; - } - file.close(); - return result; - } - result = checkActionReply(); - if (result != RETURN_OK) { - if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { - uartComIF->flushUartRxBuffer(comCookie); - retries++; - continue; - } - file.close(); - return result; - } - result = checkFlashActionReply(req.region, req.address, req.length); - if (result != RETURN_OK) { - if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { - uartComIF->flushUartRxBuffer(comCookie); - retries++; - continue; - } - file.close(); - return result; - } - file.write(reinterpret_cast(datalinkLayer.getReply() + FLASH_READ_DATA_OFFSET), - req.length); - bytesRead += req.length; - retries = 0; - } - file.close(); - return RETURN_OK; -} - -ReturnValue_t StrHelper::performFpgaDownload() { - ReturnValue_t result; - struct DownloadFPGAImageActionRequest req; - uint32_t size = 0; - uint32_t retries = 0; - Timestamp timestamp; - std::string image = fpgaDownload.path + "/" + timestamp.str() + fpgaDownload.fileName; - std::ofstream file(image, std::ios_base::app | std::ios_base::out); - if(not std::filesystem::exists(image)) { - return FILE_CREATION_FAILED; - } - req.pos = fpgaDownload.startPosition; - while(req.pos < fpgaDownload.length) { - if (terminate) { - return RETURN_OK; - } - if (fpgaDownload.length - req.pos >= FpgaDownload::MAX_DATA) { - req.length = FpgaDownload::MAX_DATA; - } - else { - req.length = fpgaDownload.length - req.pos; - } - arc_pack_downloadfpgaimage_action_req(&req, commandBuffer, &size); - result = sendAndRead(size, req.pos); - if (result != RETURN_OK) { - if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { - uartComIF->flushUartRxBuffer(comCookie); - retries++; - continue; - } - file.close(); - return result; - } - result = checkFpgaActionReply(req.pos, req.length); - if (result != RETURN_OK) { - if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { - uartComIF->flushUartRxBuffer(comCookie); - retries++; - continue; - } - file.close(); - return result; - } - file.write(reinterpret_cast(datalinkLayer.getReply() + FpgaDownload::DATA_OFFSET), - req.length); - req.pos += req.length; - retries = 0; - } - file.close(); - return RETURN_OK; -} - -ReturnValue_t StrHelper::performFpgaUpload() { - ReturnValue_t result = RETURN_OK; - uint32_t commandSize = 0; - uint32_t bytesUploaded = 0; - uint32_t fileSize = 0; - struct UploadFPGAImageActionRequest req; - if (not std::filesystem::exists(fpgaUpload.uploadFile)) { - triggerEvent(STR_HELPER_FILE_NOT_EXISTS, static_cast(internalState)); - internalState = InternalState::IDLE; - return RETURN_FAILED; - } - std::ifstream file(flashWrite.fullname, std::ifstream::binary); - file.seekg(0, file.end); - fileSize = file.tellg(); - req.pos = 0; - while(bytesUploaded <= fileSize) { - if (terminate) { - return RETURN_OK; - } - if (fileSize - bytesUploaded > FpgaUpload::MAX_DATA) { - req.length = FpgaUpload::MAX_DATA; - } - else { - req.length = fileSize - bytesUploaded; - } - file.seekg(bytesUploaded, file.beg); - file.read(reinterpret_cast(req.data), req.length); - arc_pack_uploadfpgaimage_action_req(&req, commandBuffer, &commandSize); - result = sendAndRead(commandSize, req.pos); - if (result != RETURN_OK) { - return RETURN_FAILED; - } - result = checkFpgaActionReply(req.pos, req.length); - if (result != RETURN_OK) { - return result; - } - bytesUploaded += req.length; - } - return RETURN_OK; -} - -ReturnValue_t StrHelper::sendAndRead(size_t size, uint32_t parameter) { - ReturnValue_t result = RETURN_OK; - ReturnValue_t decResult = RETURN_OK; - size_t receivedDataLen = 0; - uint8_t *receivedData = nullptr; - size_t bytesLeft = 0; - uint32_t missedReplies = 0; - datalinkLayer.encodeFrame(commandBuffer, size); - result = uartComIF->sendMessage(comCookie, datalinkLayer.getEncodedFrame(), - datalinkLayer.getEncodedLength()); - if (result != RETURN_OK) { - sif::warning << "StrHelper::sendAndRead: Failed to send packet" << std::endl; - triggerEvent(STR_HELPER_SENDING_PACKET_FAILED, result, parameter); - return RETURN_FAILED; - } - decResult = ArcsecDatalinkLayer::DEC_IN_PROGRESS; - while (decResult == ArcsecDatalinkLayer::DEC_IN_PROGRESS) { - result = uartComIF->requestReceiveMessage(comCookie, - StarTracker::MAX_FRAME_SIZE * 2 + 2); - if (result != RETURN_OK) { - sif::warning << "StrHelper::sendAndRead: Failed to request reply" << std::endl; - triggerEvent(STR_HELPER_REQUESTING_MSG_FAILED, result, parameter); - return RETURN_FAILED; - } - result = uartComIF->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); - if (result != RETURN_OK) { - sif::warning << "StrHelper::sendAndRead: Failed to read received message" << std::endl; - triggerEvent(STR_HELPER_READING_REPLY_FAILED, result, parameter); - return RETURN_FAILED; - } - if (receivedDataLen == 0 && missedReplies < MAX_POLLS) { - missedReplies++; - continue; - } - else if ((receivedDataLen == 0) && (missedReplies >= MAX_POLLS)) { - triggerEvent(STR_HELPER_NO_REPLY, parameter); - return RETURN_FAILED; - } - else { - missedReplies = 0; - } - decResult = datalinkLayer.decodeFrame(receivedData, receivedDataLen, &bytesLeft); - if (bytesLeft != 0) { - // This should never happen - sif::warning << "StrHelper::sendAndRead: Bytes left after decoding" << std::endl; - triggerEvent(STR_HELPER_COM_ERROR, result, parameter); - return RETURN_FAILED; - } - } - if (decResult != RETURN_OK) { - triggerEvent(STR_HELPER_DEC_ERROR, decResult, parameter); - return RETURN_FAILED; - } - return RETURN_OK; -} - -ReturnValue_t StrHelper::checkActionReply() { - uint8_t type = datalinkLayer.getReplyFrameType(); - if (type != TMTC_ACTIONREPLY) { - sif::warning << "StrHelper::checkActionReply: Received reply with invalid type ID" - << std::endl; - return INVALID_TYPE_ID; - } - uint8_t status = datalinkLayer.getStatusField(); - if (status != ArcsecDatalinkLayer::STATUS_OK) { - sif::warning << "StrHelper::checkActionReply: Status failure: " - << static_cast(status) << std::endl; - return STATUS_ERROR; - } - return RETURN_OK; -} - -ReturnValue_t StrHelper::checkReplyPosition(uint32_t expectedPosition) { - uint32_t receivedPosition = 0; - std::memcpy(&receivedPosition, datalinkLayer.getReply() + POS_OFFSET, sizeof(receivedPosition)); - if (receivedPosition != expectedPosition) { - triggerEvent(POSITION_MISMATCH, receivedPosition); - return RETURN_FAILED; - } - return RETURN_OK; -} - -ReturnValue_t StrHelper::checkFlashActionReply(uint8_t region_, uint32_t address_, - uint16_t length_) { - ReturnValue_t result = RETURN_OK; - result = checkActionReply(); - if (result != RETURN_OK) { - return result; - } - const uint8_t* data = datalinkLayer.getReply(); - uint8_t region = *(data + REGION_OFFSET); - uint32_t address; - const uint8_t* addressData = data + ADDRESS_OFFSET; - size_t size = sizeof(address); - result = SerializeAdapter::deSerialize(&address, &addressData, &size, - SerializeIF::Endianness::LITTLE); - if (result != RETURN_OK) { - sif::warning << "StrHelper::checkFlashActionReply: Deserialization of address failed" - << std::endl; - return result; - } - uint16_t length; - size = sizeof(length); - const uint8_t* lengthData = data + LENGTH_OFFSET; - result = SerializeAdapter::deSerialize(&length, lengthData, &size, - SerializeIF::Endianness::LITTLE); - if (result != RETURN_OK) { - sif::warning << "StrHelper::checkFlashActionReply: Deserialization of length failed" - << std::endl; - } - if (region != region_) { - return REGION_MISMATCH; - } - if (address != address_) { - return ADDRESS_MISMATCH; - } - if (length != length_) { - return LENGTH_MISMATCH; - } - return RETURN_OK; -} - -ReturnValue_t StrHelper::checkFpgaActionReply(uint32_t expectedPosition, - uint32_t expectedLength) { - ReturnValue_t result = RETURN_OK; - result = checkActionReply(); - if (result != RETURN_OK) { - return result; - } - const uint8_t* data = datalinkLayer.getReply() + ACTION_DATA_OFFSET; - uint32_t position; - size_t size = sizeof(position); - result = SerializeAdapter::deSerialize(&position, &data, &size, - SerializeIF::Endianness::LITTLE); - if (result != RETURN_OK) { - sif::warning << "StrHelper::checkFpgaActionReply: Deserialization of position failed" - << std::endl; - return result; - } - uint32_t length; - size = sizeof(length); - result = SerializeAdapter::deSerialize(&length, &data, &size, - SerializeIF::Endianness::LITTLE); - if (result != RETURN_OK) { - sif::warning << "StrHelper::checkFpgaActionReply: Deserialization of length failed" - << std::endl; - return result; - } - return result; -} - -ReturnValue_t StrHelper::checkPath(std::string name) { - if (name.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT)) - == std::string(SdCardManager::SD_0_MOUNT_POINT)) { - if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { - sif::warning << "StrHelper::checkPath: SD card 0 not mounted" << std::endl; - return SD_NOT_MOUNTED; - } - } else if (name.substr(0, sizeof(SdCardManager::SD_1_MOUNT_POINT)) - == std::string(SdCardManager::SD_1_MOUNT_POINT)) { - if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { - sif::warning << "StrHelper::checkPath: SD card 1 not mounted" << std::endl; - return SD_NOT_MOUNTED; - } - } - return RETURN_OK; -} diff --git a/bsp_q7s/devices/startracker/StrHelper.h b/bsp_q7s/devices/startracker/StrHelper.h deleted file mode 100644 index e140a4d6..00000000 --- a/bsp_q7s/devices/startracker/StrHelper.h +++ /dev/null @@ -1,397 +0,0 @@ -#ifndef BSP_Q7S_DEVICES_STRHELPER_H_ -#define BSP_Q7S_DEVICES_STRHELPER_H_ - -#include -#include "ArcsecDatalinkLayer.h" -#include "fsfw/osal/linux/BinarySemaphore.h" -#include "bsp_q7s/memory/SdCardManager.h" -#include "fsfw/returnvalues/HasReturnvaluesIF.h" -#include "fsfw/objectmanager/SystemObject.h" -#include "fsfw/tasks/ExecutableObjectIF.h" -#include "fsfw_hal/linux/uart/UartComIF.h" -#include "fsfw/devicehandlers/CookieIF.h" - -extern "C" { - #include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h" - #include "thirdparty/arcsec_star_tracker/client/generated/actionreq.h" -} - -/** - * @brief Helper class for the star tracker handler to accelerate large data transfers. - */ -class StrHelper: public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF { -public: - - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HELPER; - - //! [EXPORT] : [COMMENT] Image upload failed - static const Event IMAGE_UPLOAD_FAILED = MAKE_EVENT(0, severity::LOW); - //! [EXPORT] : [COMMENT] Image download failed - static const Event IMAGE_DOWNLOAD_FAILED = MAKE_EVENT(1, severity::LOW); - //! [EXPORT] : [COMMENT] Uploading image to star tracker was successfulop - static const Event IMAGE_UPLOAD_SUCCESSFUL = MAKE_EVENT(2, severity::LOW); - //! [EXPORT] : [COMMENT] Image download was successful - static const Event IMAGE_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(3, severity::LOW); - //! [EXPORT] : [COMMENT] Finished flash write procedure successfully - static const Event FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(4, severity::LOW); - //! [EXPORT] : [COMMENT] Finished flash read procedure successfully - static const Event FLASH_READ_SUCCESSFUL = MAKE_EVENT(5, severity::LOW); - //! [EXPORT] : [COMMENT] Flash write procedure failed - static const Event FLASH_WRITE_FAILED = MAKE_EVENT(6, severity::LOW); - //! [EXPORT] : [COMMENT] Flash read procedure failed - static const Event FLASH_READ_FAILED = MAKE_EVENT(7, severity::LOW); - //! [EXPORT] : [COMMENT] Download of FPGA image successful - static const Event FPGA_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(8, severity::LOW); - //! [EXPORT] : [COMMENT] Download of FPGA image failed - static const Event FPGA_DOWNLOAD_FAILED = MAKE_EVENT(9, severity::LOW); - //! [EXPORT] : [COMMENT] Upload of FPGA image successful - static const Event FPGA_UPLOAD_SUCCESSFUL = MAKE_EVENT(10, severity::LOW); - //! [EXPORT] : [COMMENT] Upload of FPGA image failed - static const Event FPGA_UPLOAD_FAILED = MAKE_EVENT(11, severity::LOW); - //! [EXPORT] : [COMMENT] Failed to read communication interface reply data - //!P1: Return code of failed communication interface read call - //!P1: Upload/download position for which the read call failed - static const Event STR_HELPER_READING_REPLY_FAILED = MAKE_EVENT(12, severity::LOW); - //! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence - //!P1: Return code of failed communication interface read call - //!P1: Upload/download position for which the read call failed - static const Event STR_HELPER_COM_ERROR = MAKE_EVENT(13, severity::LOW); - //! [EXPORT] : [COMMENT] Star tracker did not send replies (maybe device is powered off) - //!P1: Position of upload or download packet for which no reply was sent - static const Event STR_HELPER_NO_REPLY = MAKE_EVENT(14, severity::LOW); - //! [EXPORT] : [COMMENT] Error during decoding of received reply occurred - //P1: Return value of decoding function - //P2: Position of upload/download packet, or address of flash write/read request - static const Event STR_HELPER_DEC_ERROR = MAKE_EVENT(15, severity::LOW); - //! [EXPORT] : [COMMENT] Position mismatch - //! P1: The expected position and thus the position for which the image upload/download failed - static const Event POSITION_MISMATCH = MAKE_EVENT(16, severity::LOW); - //! [EXPORT] : [COMMENT] Specified file does not exist - //!P1: Internal state of str helper - static const Event STR_HELPER_FILE_NOT_EXISTS = MAKE_EVENT(17, severity::LOW); - //! [EXPORT] : [COMMENT] Sending packet to star tracker failed - //!P1: Return code of communication interface sendMessage function - //!P2: Position of upload/download packet, or address of flash write/read request for which sending failed - static const Event STR_HELPER_SENDING_PACKET_FAILED = MAKE_EVENT(18, severity::LOW); - //! [EXPORT] : [COMMENT] Communication interface requesting reply failed - //!P1: Return code of failed request - //!P1: Upload/download position, or address of flash write/read request for which transmission failed - static const Event STR_HELPER_REQUESTING_MSG_FAILED = MAKE_EVENT(19, severity::LOW); - - StrHelper(object_id_t objectId); - virtual ~StrHelper(); - - ReturnValue_t initialize() override; - ReturnValue_t performOperation(uint8_t operationCode = 0) override; - - ReturnValue_t setComIF(DeviceCommunicationIF* communicationInterface_); - void setComCookie(CookieIF* comCookie_); - - /** - * @brief Starts sequence to upload image to star tracker - * - * @param uploadImage_ Name including absolute path of the image to upload. Must be previously - * transferred to the OBC with the CFDP protocol. - */ - ReturnValue_t startImageUpload(std::string uploadImage_); - - /** - * @brief Calling this function initiates the download of an image from the star tracker. - * - * @param path Path where downloaded image will be stored - */ - ReturnValue_t startImageDownload(std::string path); - - /** - * @brief Starts the flash write procedure - * - * @param fullname Full name including absolute path of file to write to flash - * @param region Region ID of flash region to write to - * @param address Start address of flash write procedure - */ - ReturnValue_t startFlashWrite(std::string fullname, uint8_t region, uint32_t address); - - /** - * @brief Starts the flash read procedure - * - * @param path Path where file with read flash data will be created - * @param region Region ID of flash region to read from - * @param address Start address of flash section to read - * @param length Number of bytes to read from flash - */ - ReturnValue_t startFlashRead(std::string path, uint8_t region, uint32_t address, - uint32_t length); - - /** - * @brief Starts the download of the FPGA image - * - * @param path The path where the file with the downloaded data will be created - * @param startPosition Offset in fpga image to read from - * @param length Number of bytes to dwonload from the FPGA image - * - */ - ReturnValue_t startFpgaDownload(std::string path, uint32_t startPosition, uint32_t length); - - /** - * @brief Starts upload of new image to FPGA - * - * @param uploadFile Full name of file containing FPGA image data - */ - ReturnValue_t startFpgaUpload(std::string uploadFile); - - /** - * @brief Can be used to interrupt a running data transfer. - */ - void stopProcess(); - - /** - * @brief Changes the dafault name of downloaded images - */ - void setDownloadImageName(std::string filename); - - /** - * @brief Sets the name of the file which will be created to store the data read from flash - */ - void setFlashReadFilename(std::string filename); - - /** - * @brief Set download FPGA image name - */ - void setDownloadFpgaImage(std::string filename); - -private: - - static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER; - - //! [EXPORT] : [COMMENT] SD card specified in path string not mounted - static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA0); - //! [EXPORT] : [COMMENT] Specified file does not exist on filesystem - static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA1); - //! [EXPORT] : [COMMENT] Specified path does not exist - static const ReturnValue_t PATH_NOT_EXISTS = MAKE_RETURN_CODE(0xA2); - //! [EXPORT] : [COMMENT] Failed to create download image or read flash file - static const ReturnValue_t FILE_CREATION_FAILED = MAKE_RETURN_CODE(0xA3); - //! [EXPORT] : [COMMENT] Region in flash write/read reply does not match expected region - static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(0xA4); - //! [EXPORT] : [COMMENT] Address in flash write/read reply does not match expected address - static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(0xA5); - //! [EXPORT] : [COMMENT] Length in flash write/read reply does not match expected length - static const ReturnValue_t LENGTH_MISMATCH = MAKE_RETURN_CODE(0xA6); - //! [EXPORT] : [COMMENT] Status field in reply signals error - static const ReturnValue_t STATUS_ERROR = MAKE_RETURN_CODE(0xA7); - //! [EXPORT] : [COMMENT] Reply has invalid type ID (should be of action reply type) - static const ReturnValue_t INVALID_TYPE_ID = MAKE_RETURN_CODE(0xA8); - - // Size of one image part which can be sent per action request - static const size_t SIZE_IMAGE_PART = 1024; - - class ImageDownload { - public: - static const uint32_t LAST_POSITION = 4095; - }; - - class FpgaDownload { - public: - static const uint16_t MAX_DATA = 1024; - static const uint8_t DATA_OFFSET = 10; - // Start position of fpga image part to download - uint32_t startPosition = 0; - // Length of image part to download - uint32_t length = 0; - // Path where downloaded FPGA image will be stored - std::string path; - // Name of file containing downloaded FPGA image - std::string fileName = "fpgaimage.bin"; - }; - FpgaDownload fpgaDownload; - - class FpgaUpload { - public: - static const uint32_t MAX_DATA = 1024; - // Full name of file to upload - std::string uploadFile; - }; - FpgaUpload fpgaUpload; - - static const uint32_t MAX_POLLS = 10000; - - static const uint8_t ACTION_DATA_OFFSET = 2; - static const uint8_t POS_OFFSET = 2; - static const uint8_t IMAGE_DATA_OFFSET = 5; - static const uint8_t FLASH_READ_DATA_OFFSET = 8; - static const uint8_t REGION_OFFSET = 2; - static const uint8_t ADDRESS_OFFSET = 3; - static const uint8_t LENGTH_OFFSET = 7; - static const size_t IMAGE_DATA_SIZE = 1024; - static const size_t MAX_FLASH_DATA = 1024; - static const size_t CONFIG_MAX_DOWNLOAD_RETRIES = 3; - - enum class InternalState { - IDLE, - UPLOAD_IMAGE, - DOWNLOAD_IMAGE, - FLASH_WRITE, - FLASH_READ, - DOWNLOAD_FPGA_IMAGE, - UPLOAD_FPGA_IMAGE - }; - - InternalState internalState = InternalState::IDLE; - - ArcsecDatalinkLayer datalinkLayer; - - BinarySemaphore semaphore; - - class UploadImage { - public: - // Name including absolute path of image to upload - std::string uploadFile; - }; - UploadImage uploadImage; - - class DownloadImage { - public: - // Path where the downloaded image will be stored - std::string path; - // Default name of downloaded image, can be changed via command - std::string filename = "image.bin"; - }; - DownloadImage downloadImage; - - class FlashWrite { - public: - // File which contains data to write when executing the flash write command - std::string fullname; - // Will be set with the flash write command - uint8_t region = 0; - // Will be set with the flash write command and specifies the start address where to write the - // flash data to - uint32_t address = 0; - }; - FlashWrite flashWrite; - - class FlashRead { - public: - // Path where the file containing the read data will be stored - std::string path = ""; - // Default name of file containing the data read from flash, can be changed via command - std::string filename = "flashread.bin"; - // Will be set with the flash read command - uint8_t region = 0; - // Will be set with the flash read command and specifies the start address of the flash section - // to read - uint32_t address = 0; - // Number of bytes to read from flash - uint32_t size = 0; - }; - FlashRead flashRead; - - SdCardManager* sdcMan = nullptr; - - uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; - - bool terminate = false; - - /** - * UART communication object responsible for low level access of star tracker - * Must be set by star tracker handler - */ - UartComIF* uartComIF = nullptr; - // Communication cookie. Must be set by the star tracker handler - CookieIF* comCookie = nullptr; - - // Queue id of raw data receiver - MessageQueueId_t rawDataReceiver = MessageQueueIF::NO_QUEUE; - - /** - * @brief Performs image uploading - */ - ReturnValue_t performImageUpload(); - - /** - * @brief Performs download of last taken image from the star tracker. - * - * @details Download is split over multiple packets transporting each a maximum of 1024 bytes. - * In case the download of one position fails, the same packet will be again - * requested. If the download of the packet fails CONFIG_MAX_DOWNLOAD_RETRIES times, - * the download will be stopped. - */ - ReturnValue_t performImageDownload(); - - /** - * @brief Handles flash write procedure - * - * @return RETURN_OK if successful, otherwise RETURN_FAILED - */ - ReturnValue_t performFlashWrite(); - - /** - * @brief Sends a sequence of commands to the star tracker to read larger parts from the - * flash memory. - */ - ReturnValue_t performFlashRead(); - - /** - * @brief Performs the download of the FPGA image which requires to be slip over multiple - * action requests. - */ - ReturnValue_t performFpgaDownload(); - - /** - * @brief Performs upload of new FPGA image. Upload sequence split over multiple commands - * because one command can only transport 1024 bytes of image data. - */ - ReturnValue_t performFpgaUpload(); - - /** - * @brief Sends packet to the star tracker and reads reply by using the communication - * interface - * - * @param size Size of data beforehand written to the commandBuffer - * @param parameter Parameter 2 of trigger event function - * - * @return RETURN_OK if successful, otherwise RETURN_FAILED - */ - ReturnValue_t sendAndRead(size_t size, uint32_t parameter); - - /** - * @brief Checks the header (type id and status fields) of the action reply - * - * @return RETURN_OK if reply confirms success of packet transfer, otherwise REUTRN_FAILED - */ - ReturnValue_t checkActionReply(); - - /** - * @brief Checks the position field in a star tracker upload/download reply. - * - * @param expectedPosition Value of expected position - * - * @return RETURN_OK if received position matches expected position, otherwise RETURN_FAILED - */ - ReturnValue_t checkReplyPosition(uint32_t expectedPosition); - - /** - * @brief Checks the region, address and length value of a flash write or read reply. - * - * @return RETURN_OK if values match expected values, otherwise appropriate error return - * value. - */ - ReturnValue_t checkFlashActionReply(uint8_t region_, uint32_t address_, uint16_t length_); - - /** - * @brief Checks the reply to the fpga download and upload request - * - * @param expectedPosition The expected position value in the reply - * @param expectedLength The expected length field in the reply - */ - ReturnValue_t checkFpgaActionReply(uint32_t expectedPosition, uint32_t expectedLength); - - /** - * @brief Checks if a path points to an sd card and whether the SD card is monuted. - * - * @return SD_NOT_MOUNTED id SD card is not mounted, otherwise RETURN_OK - */ - ReturnValue_t checkPath(std::string name); -}; - -#endif /* BSP_Q7S_DEVICES_STRHELPER_H_ */ diff --git a/bsp_q7s/gpio/CMakeLists.txt b/bsp_q7s/gpio/CMakeLists.txt deleted file mode 100644 index dd657546..00000000 --- a/bsp_q7s/gpio/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -target_sources(${TARGET_NAME} PRIVATE - gpioCallbacks.cpp -) diff --git a/bsp_q7s/gpio/gpioCallbacks.cpp b/bsp_q7s/gpio/gpioCallbacks.cpp deleted file mode 100644 index 2cbf3320..00000000 --- a/bsp_q7s/gpio/gpioCallbacks.cpp +++ /dev/null @@ -1,512 +0,0 @@ -#include "gpioCallbacks.h" -#include "busConf.h" -#include - -#include -#include -#include - - -namespace gpioCallbacks { - -GpioIF* gpioComInterface; - -void initSpiCsDecoder(GpioIF* gpioComIF) { - - ReturnValue_t result; - - if (gpioComIF == nullptr) { - sif::debug << "initSpiCsDecoder: Invalid gpioComIF" << std::endl; - return; - } - - gpioComInterface = gpioComIF; - - GpioCookie* spiMuxGpios = new GpioCookie; - - GpiodRegularByLineName* spiMuxBit = nullptr; - /** Setting mux bit 1 to low will disable IC21 on the interface board */ - spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_1_PIN, "SPI Mux Bit 1", - gpio::DIR_OUT, gpio::HIGH); - spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit); - /** Setting mux bit 2 to low disables IC1 on the TCS board */ - spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_2_PIN, "SPI Mux Bit 2", - gpio::DIR_OUT, gpio::HIGH); - spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit); - /** Setting mux bit 3 to low disables IC2 on the TCS board and IC22 on the interface board */ - spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_3_PIN, "SPI Mux Bit 3", - gpio::DIR_OUT, gpio::LOW); - spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit); - -// spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_1_PIN, "SPI Mux Bit 1", -// gpio::OUT, gpio::LOW); -// spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit); -// /** Setting mux bit 2 to low disables IC1 on the TCS board */ -// spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_2_PIN, "SPI Mux Bit 2", gpio::OUT, gpio::HIGH); -// spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit); -// /** Setting mux bit 3 to low disables IC2 on the TCS board and IC22 on the interface board */ -// spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_3_PIN, "SPI Mux Bit 3", gpio::OUT, gpio::LOW); -// spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit); - - /** The following gpios can take arbitrary initial values */ - spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_4_PIN, "SPI Mux Bit 4", - gpio::DIR_OUT, gpio::LOW); - spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_4, spiMuxBit); - spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_5_PIN, "SPI Mux Bit 5", - gpio::DIR_OUT, gpio::LOW); - spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_5, spiMuxBit); - spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_6_PIN, "SPI Mux Bit 6", - gpio::DIR_OUT, gpio::LOW); - spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_6, spiMuxBit); - GpiodRegularByLineName* enRwDecoder = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_CS, - "EN_RW_CS", gpio::DIR_OUT, gpio::HIGH); - spiMuxGpios->addGpio(gpioIds::EN_RW_CS, enRwDecoder); - - result = gpioComInterface->addGpios(spiMuxGpios); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "initSpiCsDecoder: Failed to add mux bit gpios to gpioComIF" << std::endl; - return; - } -} - -void spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, gpio::Levels value, - void* args) { - - if (gpioComInterface == nullptr) { - sif::debug << "spiCsDecoderCallback: No gpioComIF specified. Call initSpiCsDecoder " - << "to specify gpioComIF" << std::endl; - return; - } - - /* Reading is not supported by the callback function */ - if (gpioOp == gpio::GpioOperation::READ) { - return; - } - - if (value == gpio::HIGH) { - switch (gpioId) { - case(gpioIds::RTD_IC_3): { - disableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_4): { - disableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_5): { - disableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_6): { - disableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_7): { - disableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_8): { - disableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_9): { - disableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_10): { - disableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_11): { - disableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_12): { - disableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_13): { - disableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_14): { - disableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_15): { - disableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_16): { - disableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_17): { - disableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_18): { - disableDecoderTcsIc2(); - break; - } - case(gpioIds::CS_SUS_1): { - disableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_2): { - disableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_3): { - disableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_4): { - disableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_5): { - disableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_6): { - disableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_7): { - disableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_8): { - disableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_9): { - disableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_10): { - disableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_11): { - disableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_12): { - disableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_13): { - disableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_RW1): { - disableRwDecoder(); - break; - } - case(gpioIds::CS_RW2): { - disableRwDecoder(); - break; - } - case(gpioIds::CS_RW3): { - disableRwDecoder(); - break; - } - case(gpioIds::CS_RW4): { - disableRwDecoder(); - break; - } - default: - sif::debug << "spiCsDecoderCallback: Invalid gpio id " << gpioId << std::endl; - } - } - else if (value == gpio::LOW) { - switch (gpioId) { - case(gpioIds::RTD_IC_3): { - selectY7(); - enableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_4): { - selectY6(); - enableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_5): { - selectY5(); - enableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_6): { - selectY4(); - enableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_7): { - selectY3(); - enableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_8): { - selectY2(); - enableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_9): { - selectY1(); - enableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_10): { - selectY0(); - enableDecoderTcsIc1(); - break; - } - case(gpioIds::RTD_IC_11): { - selectY7(); - enableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_12): { - selectY6(); - enableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_13): { - selectY5(); - enableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_14): { - selectY4(); - enableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_15): { - selectY3(); - enableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_16): { - selectY2(); - enableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_17): { - selectY1(); - enableDecoderTcsIc2(); - break; - } - case(gpioIds::RTD_IC_18): { - selectY0(); - enableDecoderTcsIc2(); - break; - } - case(gpioIds::CS_SUS_1): { - selectY0(); - enableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_2): { - selectY1(); - enableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_3): { - selectY0(); - enableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_4): { - selectY1(); - enableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_5): { - selectY2(); - enableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_6): { - selectY2(); - enableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_7): { - selectY3(); - enableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_8): { - selectY3(); - enableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_9): { - selectY4(); - enableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_10): { - selectY5(); - enableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_SUS_11): { - selectY4(); - enableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_12): { - selectY5(); - enableDecoderInterfaceBoardIc2(); - break; - } - case(gpioIds::CS_SUS_13): { - selectY6(); - enableDecoderInterfaceBoardIc1(); - break; - } - case(gpioIds::CS_RW1): { - selectY0(); - enableRwDecoder(); - break; - } - case(gpioIds::CS_RW2): { - selectY1(); - enableRwDecoder(); - break; - } - case(gpioIds::CS_RW3): { - selectY2(); - enableRwDecoder(); - break; - } - case(gpioIds::CS_RW4): { - selectY3(); - enableRwDecoder(); - break; - } - default: - sif::debug << "spiCsDecoderCallback: Invalid gpio id " << gpioId << std::endl; - } - } - else { - sif::debug << "spiCsDecoderCallback: Invalid value. Must be 0 or 1" << std::endl; - } -} - -void enableDecoderTcsIc1() { - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3); -} - -void enableDecoderTcsIc2() { - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2); -} - -void enableDecoderInterfaceBoardIc1() { - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3); -} - -void enableDecoderInterfaceBoardIc2() { - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2); -} - -void disableDecoderTcsIc1() { - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3); -} - -void disableDecoderTcsIc2() { - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2); -} - -void disableDecoderInterfaceBoardIc1() { - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3); -} - -void disableDecoderInterfaceBoardIc2() { - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3); -} - -void enableRwDecoder() { - gpioComInterface->pullHigh(gpioIds::EN_RW_CS); -} - -void disableRwDecoder() { - gpioComInterface->pullLow(gpioIds::EN_RW_CS); -} - -void selectY0() { - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6); -} - -void selectY1() { - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6); -} - -void selectY2() { - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6); -} - -void selectY3() { - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6); -} - -void selectY4() { - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6); -} - -void selectY5() { - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6); -} - -void selectY6() { - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6); -} - -void selectY7() { - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5); - gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6); -} - -void disableAllDecoder() { - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1); - gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2); - gpioComInterface->pullLow(gpioIds::EN_RW_CS); -} - -} diff --git a/bsp_q7s/gpio/gpioCallbacks.h b/bsp_q7s/gpio/gpioCallbacks.h deleted file mode 100644 index 18adb52b..00000000 --- a/bsp_q7s/gpio/gpioCallbacks.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef LINUX_GPIO_GPIOCALLBACKS_H_ -#define LINUX_GPIO_GPIOCALLBACKS_H_ - -#include -#include - - -namespace gpioCallbacks { - - /** - * @brief This function initializes the GPIOs used to control the SN74LVC138APWR decoders on - * the TCS Board and the interface board. - */ - void initSpiCsDecoder(GpioIF* gpioComIF); - - /** - * @brief This function implements the decoding to multiply gpios by using the decoder - * chips SN74LVC138APWR on the TCS board and the interface board. - */ - void spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, - gpio::Levels value, void* args); - - /** - * @brief This function sets mux bits 1-3 to a state which will only enable the decoder - * on the TCS board which is named to IC1 in the schematic. - */ - void enableDecoderTcsIc1(); - - /** - * @brief This function sets mux bits 1-3 to a state which will only enable the decoder - * on the TCS board which is named to IC2 in the schematic. - */ - void enableDecoderTcsIc2(); - - /** - * @brief This function sets mux bits 1-3 to a state which will only enable the decoder - * on the inteface board board which is named to IC21 in the schematic. - */ - void enableDecoderInterfaceBoardIc1(); - - /** - * @brief This function sets mux bits 1-3 to a state which will only enable the decoder - * on the inteface board board which is named to IC22 in the schematic. - */ - void enableDecoderInterfaceBoardIc2(); - - void disableDecoderTcsIc1(); - void disableDecoderTcsIc2(); - void disableDecoderInterfaceBoardIc1(); - void disableDecoderInterfaceBoardIc2(); - - /** - * @brief Enables the reaction wheel chip select decoder (IC3). - */ - void enableRwDecoder(); - void disableRwDecoder(); - - /** - * @brief This function disables all decoder. - */ - void disableAllDecoder(); - - /** The following functions enable the appropriate channel of the currently enabled decoder */ - void selectY0(); - void selectY1(); - void selectY2(); - void selectY3(); - void selectY4(); - void selectY5(); - void selectY6(); - void selectY7(); -} - -#endif /* LINUX_GPIO_GPIOCALLBACKS_H_ */ diff --git a/bsp_q7s/main.cpp b/bsp_q7s/main.cpp index 9ce0dca2..dfcaebf0 100644 --- a/bsp_q7s/main.cpp +++ b/bsp_q7s/main.cpp @@ -12,12 +12,11 @@ * @brief This is the main program for the target hardware. * @return */ -int main(void) -{ - using namespace std; +int main(void) { + using namespace std; #if Q7S_SIMPLE_MODE == 0 - return obsw::obsw(); + return obsw::obsw(); #else - return simple::simple(); + return simple::simple(); #endif } diff --git a/bsp_q7s/memory/CMakeLists.txt b/bsp_q7s/memory/CMakeLists.txt index 6c7d0a94..a0d4f66f 100644 --- a/bsp_q7s/memory/CMakeLists.txt +++ b/bsp_q7s/memory/CMakeLists.txt @@ -1,5 +1,6 @@ -target_sources(${TARGET_NAME} PRIVATE +target_sources(${OBSW_NAME} PRIVATE FileSystemHandler.cpp SdCardManager.cpp scratchApi.cpp + FilesystemHelper.cpp ) \ No newline at end of file diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index caad94a6..7a4a791c 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -1,257 +1,243 @@ #include "FileSystemHandler.h" -#include "bsp_q7s/core/CoreController.h" - -#include "fsfw/tasks/TaskFactory.h" -#include "fsfw/memory/GenericFileSystemMessage.h" -#include "fsfw/ipc/QueueFactory.h" - #include -#include #include +#include -FileSystemHandler::FileSystemHandler(object_id_t fileSystemHandler): - SystemObject(fileSystemHandler) { - mq = QueueFactory::instance()->createMessageQueue(FS_MAX_QUEUE_SIZE); +#include "bsp_q7s/core/CoreController.h" +#include "fsfw/ipc/QueueFactory.h" +#include "fsfw/memory/GenericFileSystemMessage.h" +#include "fsfw/tasks/TaskFactory.h" + +FileSystemHandler::FileSystemHandler(object_id_t fileSystemHandler) + : SystemObject(fileSystemHandler) { + auto mqArgs = MqArgs(this->getObjectId()); + mq = QueueFactory::instance()->createMessageQueue(FS_MAX_QUEUE_SIZE, + MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); } -FileSystemHandler::~FileSystemHandler() { - QueueFactory::instance()->deleteMessageQueue(mq); -} +FileSystemHandler::~FileSystemHandler() { QueueFactory::instance()->deleteMessageQueue(mq); } ReturnValue_t FileSystemHandler::performOperation(uint8_t unsignedChar) { - while(true) { - try { - fileSystemHandlerLoop(); - } - catch(std::bad_alloc& e) { - // Restart OBSW, hints at a memory leak - sif::error << "Allocation error in FileSystemHandler::performOperation" - << e.what() << std::endl; - // Set up an error file or a special flag in the scratch buffer for these cases - triggerEvent(CoreController::ALLOC_FAILURE, 0 , 0); - CoreController::incrementAllocationFailureCount(); - } + while (true) { + try { + fileSystemHandlerLoop(); + } catch (std::bad_alloc& e) { + // Restart OBSW, hints at a memory leak + sif::error << "Allocation error in FileSystemHandler::performOperation" << e.what() + << std::endl; + // Set up an error file or a special flag in the scratch buffer for these cases + triggerEvent(CoreController::ALLOC_FAILURE, 0, 0); + CoreController::incrementAllocationFailureCount(); } + } } - void FileSystemHandler::fileSystemHandlerLoop() { - CommandMessage filemsg; - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - while(true) { - if(opCounter % 5 == 0) { - if(coreCtrl->sdInitFinished()) { - fileSystemCheckup(); - } - } - result = mq->receiveMessage(&filemsg); - if(result == MessageQueueIF::EMPTY) { - break; - } - else if(result != HasReturnvaluesIF::RETURN_FAILED) { - sif::warning << "FileSystemHandler::performOperation: Message reception failed!" - << std::endl; - break; - } - Command_t command = filemsg.getCommand(); - switch(command) { - case(GenericFileSystemMessage::CMD_CREATE_DIRECTORY): { - break; - } - case(GenericFileSystemMessage::CMD_CREATE_FILE): { - break; - } - } - opCounter++; + CommandMessage filemsg; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + while (true) { + if (opCounter % 5 == 0) { + if (coreCtrl->sdInitFinished()) { + fileSystemCheckup(); + } + } + result = mq->receiveMessage(&filemsg); + if (result == MessageQueueIF::EMPTY) { + break; + } else if (result != HasReturnvaluesIF::RETURN_FAILED) { + sif::warning << "FileSystemHandler::performOperation: Message reception failed!" << std::endl; + break; + } + Command_t command = filemsg.getCommand(); + switch (command) { + case (GenericFileSystemMessage::CMD_CREATE_DIRECTORY): { + break; + } + case (GenericFileSystemMessage::CMD_CREATE_FILE): { + break; + } } - - // This task will have a low priority and will run permanently in the background - // so we will just run in a permanent loop here and check file system - // messages permanently opCounter++; - TaskFactory::instance()->delayTask(1000); + } + + // This task will have a low priority and will run permanently in the background + // so we will just run in a permanent loop here and check file system + // messages permanently + opCounter++; + TaskFactory::instance()->delayTask(1000); } void FileSystemHandler::fileSystemCheckup() { - SdCardManager::SdStatePair statusPair; - sdcMan->getSdCardActiveStatus(statusPair); - sd::SdCard preferredSdCard; - sdcMan->getPreferredSdCard(preferredSdCard); - if((preferredSdCard == sd::SdCard::SLOT_0) and - (statusPair.first == sd::SdState::MOUNTED)) { - currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; + SdCardManager::SdStatePair statusPair; + sdcMan->getSdCardActiveStatus(statusPair); + sd::SdCard preferredSdCard; + sdcMan->getPreferredSdCard(preferredSdCard); + if ((preferredSdCard == sd::SdCard::SLOT_0) and (statusPair.first == sd::SdState::MOUNTED)) { + currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; + } else if ((preferredSdCard == sd::SdCard::SLOT_1) and + (statusPair.second == sd::SdState::MOUNTED)) { + currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT; + } else { + std::string sdString; + if (preferredSdCard == sd::SdCard::SLOT_0) { + sdString = "0"; + } else { + sdString = "1"; } - else if((preferredSdCard == sd::SdCard::SLOT_1) and - (statusPair.second == sd::SdState::MOUNTED)) { - currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT; - } - else { - std::string sdString; - if(preferredSdCard == sd::SdCard::SLOT_0) { - sdString = "0"; - } - else { - sdString = "1"; - } - sif::warning << "FileSystemHandler::performOperation: " - "Inconsistent state detected" << std::endl; - sif::warning << "Preferred SD card is " << sdString << - " but does not appear to be mounted. Attempting fix.." << std::endl; - // This function will appear to fix the inconsistent state - ReturnValue_t result = sdcMan->sanitizeState(&statusPair, preferredSdCard); - if(result != HasReturnvaluesIF::RETURN_OK) { - // Oh no. - triggerEvent(SdCardManager::SANITIZATION_FAILED, 0, 0); - sif::error << "FileSystemHandler::fileSystemCheckup: Sanitization failed" << std::endl; - } + sif::warning << "FileSystemHandler::performOperation: " + "Inconsistent state detected" + << std::endl; + sif::warning << "Preferred SD card is " << sdString + << " but does not appear to be mounted. Attempting fix.." << std::endl; + // This function will appear to fix the inconsistent state + ReturnValue_t result = sdcMan->sanitizeState(&statusPair, preferredSdCard); + if (result != HasReturnvaluesIF::RETURN_OK) { + // Oh no. + triggerEvent(SdCardManager::SANITIZATION_FAILED, 0, 0); + sif::error << "FileSystemHandler::fileSystemCheckup: Sanitization failed" << std::endl; } + } } -MessageQueueId_t FileSystemHandler::getCommandQueue() const { - return mq->getId(); -} +MessageQueueId_t FileSystemHandler::getCommandQueue() const { return mq->getId(); } ReturnValue_t FileSystemHandler::initialize() { - coreCtrl = ObjectManager::instance()->get(objects::CORE_CONTROLLER); - if(coreCtrl == nullptr) { - sif::error << "FileSystemHandler::initialize: Could not retrieve core controller handle" << - std::endl; - } - sdcMan = SdCardManager::instance(); - sd::SdCard preferredSdCard; - ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - if(preferredSdCard == sd::SdCard::SLOT_0) { - currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; - } - else if(preferredSdCard == sd::SdCard::SLOT_1) { - currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT; - } - return HasReturnvaluesIF::RETURN_OK; + coreCtrl = ObjectManager::instance()->get(objects::CORE_CONTROLLER); + if (coreCtrl == nullptr) { + sif::error << "FileSystemHandler::initialize: Could not retrieve core controller handle" + << std::endl; + } + sdcMan = SdCardManager::instance(); + sd::SdCard preferredSdCard; + ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + if (preferredSdCard == sd::SdCard::SLOT_0) { + currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; + } else if (preferredSdCard == sd::SdCard::SLOT_1) { + currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT; + } + return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t FileSystemHandler::appendToFile(const char* repositoryPath, - const char* filename, const uint8_t* data, size_t size, - uint16_t packetNumber, FileSystemArgsIF* args) { - auto path = getInitPath(args) / repositoryPath / filename; - if(not std::filesystem::exists(path)) { - return FILE_DOES_NOT_EXIST; - } - std::ofstream file(path, std::ios_base::app|std::ios_base::out); - file.write(reinterpret_cast(data), size); - if(not file.good()) { - return GENERIC_FILE_ERROR; - } - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t FileSystemHandler::createFile(const char* repositoryPath, - const char* filename, const uint8_t* data, size_t size, FileSystemArgsIF* args) { - auto path = getInitPath(args) / filename; - if(std::filesystem::exists(path)) { - return FILE_ALREADY_EXISTS; - } - std::ofstream file(path); - file.write(reinterpret_cast(data), size); - if(not file.good()) { - return GENERIC_FILE_ERROR; - } - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t FileSystemHandler::removeFile(const char* repositoryPath, - const char* filename, FileSystemArgsIF* args) { - auto path = getInitPath(args) / repositoryPath / filename; - if(not std::filesystem::exists(path)) { - return FILE_DOES_NOT_EXIST; - } - int result = std::remove(path.c_str()); - if(result != 0) { - sif::warning << "FileSystemHandler::deleteFile: Failed with code " << result << std::endl; - return GENERIC_FILE_ERROR; - } - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t FileSystemHandler:: createDirectory(const char* repositoryPath, const char* dirname, - bool createParentDirs, FileSystemArgsIF* args) { - auto path = getInitPath(args) / repositoryPath / dirname; - if(std::filesystem::exists(path)) { - return DIRECTORY_ALREADY_EXISTS; - } - if(std::filesystem::create_directory(path)) { - return HasReturnvaluesIF::RETURN_OK; - } - sif::warning << "Creating directory " << path << " failed" << std::endl; +ReturnValue_t FileSystemHandler::appendToFile(const char* repositoryPath, const char* filename, + const uint8_t* data, size_t size, + uint16_t packetNumber, FileSystemArgsIF* args) { + auto path = getInitPath(args) / repositoryPath / filename; + if (not std::filesystem::exists(path)) { + return FILE_DOES_NOT_EXIST; + } + std::ofstream file(path, std::ios_base::app | std::ios_base::out); + file.write(reinterpret_cast(data), size); + if (not file.good()) { return GENERIC_FILE_ERROR; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t FileSystemHandler::createFile(const char* repositoryPath, const char* filename, + const uint8_t* data, size_t size, + FileSystemArgsIF* args) { + auto path = getInitPath(args) / filename; + if (std::filesystem::exists(path)) { + return FILE_ALREADY_EXISTS; + } + std::ofstream file(path); + file.write(reinterpret_cast(data), size); + if (not file.good()) { + return GENERIC_FILE_ERROR; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t FileSystemHandler::removeFile(const char* repositoryPath, const char* filename, + FileSystemArgsIF* args) { + auto path = getInitPath(args) / repositoryPath / filename; + if (not std::filesystem::exists(path)) { + return FILE_DOES_NOT_EXIST; + } + int result = std::remove(path.c_str()); + if (result != 0) { + sif::warning << "FileSystemHandler::deleteFile: Failed with code " << result << std::endl; + return GENERIC_FILE_ERROR; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t FileSystemHandler::createDirectory(const char* repositoryPath, const char* dirname, + bool createParentDirs, FileSystemArgsIF* args) { + auto path = getInitPath(args) / repositoryPath / dirname; + if (std::filesystem::exists(path)) { + return DIRECTORY_ALREADY_EXISTS; + } + if (std::filesystem::create_directory(path)) { + return HasReturnvaluesIF::RETURN_OK; + } + sif::warning << "Creating directory " << path << " failed" << std::endl; + return GENERIC_FILE_ERROR; } ReturnValue_t FileSystemHandler::removeDirectory(const char* repositoryPath, const char* dirname, - bool deleteRecurively, FileSystemArgsIF* args) { - auto path = getInitPath(args) / repositoryPath / dirname; - if(not std::filesystem::exists(path)) { - return DIRECTORY_DOES_NOT_EXIST; + bool deleteRecurively, FileSystemArgsIF* args) { + auto path = getInitPath(args) / repositoryPath / dirname; + if (not std::filesystem::exists(path)) { + return DIRECTORY_DOES_NOT_EXIST; + } + std::error_code err; + if (not deleteRecurively) { + if (std::filesystem::remove(path, err)) { + return HasReturnvaluesIF::RETURN_OK; + } else { + // Check error code. Most probably denied permissions because folder is not empty + sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with " + "code " + << err.value() << ": " << strerror(err.value()) << std::endl; + if (err.value() == ENOTEMPTY) { + return DIRECTORY_NOT_EMPTY; + } else { + return GENERIC_FILE_ERROR; + } } - std::error_code err; - if(not deleteRecurively) { - if(std::filesystem::remove(path, err)) { - return HasReturnvaluesIF::RETURN_OK; - } - else { - // Check error code. Most probably denied permissions because folder is not empty - sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with " - "code " << err.value() << ": " << strerror(err.value()) << std::endl; - if(err.value() == ENOTEMPTY) { - return DIRECTORY_NOT_EMPTY; - } - else { - return GENERIC_FILE_ERROR; - } + } else { + if (std::filesystem::remove_all(path, err)) { + return HasReturnvaluesIF::RETURN_OK; + } else { + sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with " + "code " + << err.value() << ": " << strerror(err.value()) << std::endl; + // Check error code + if (err.value() == ENOTEMPTY) { + return DIRECTORY_NOT_EMPTY; + } else { + return GENERIC_FILE_ERROR; + } + } + } - } - } - else { - if(std::filesystem::remove_all(path, err)) { - return HasReturnvaluesIF::RETURN_OK; - } - else { - sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with " - "code " << err.value() << ": " << strerror(err.value()) << std::endl; - // Check error code - if(err.value() == ENOTEMPTY) { - return DIRECTORY_NOT_EMPTY; - } - else { - return GENERIC_FILE_ERROR; - } - } - } - - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t FileSystemHandler::renameFile(const char *repositoryPath, const char *oldFilename, - const char *newFilename, FileSystemArgsIF *args) { - auto basepath = getInitPath(args) / repositoryPath; - std::filesystem::rename(basepath / oldFilename, basepath / newFilename); - return HasReturnvaluesIF::RETURN_OK; +ReturnValue_t FileSystemHandler::renameFile(const char* repositoryPath, const char* oldFilename, + const char* newFilename, FileSystemArgsIF* args) { + auto basepath = getInitPath(args) / repositoryPath; + std::filesystem::rename(basepath / oldFilename, basepath / newFilename); + return HasReturnvaluesIF::RETURN_OK; } -void FileSystemHandler::parseCfg(FsCommandCfg *cfg, bool& useMountPrefix) { - if(cfg != nullptr) { - useMountPrefix = cfg->useMountPrefix; - } +void FileSystemHandler::parseCfg(FsCommandCfg* cfg, bool& useMountPrefix) { + if (cfg != nullptr) { + useMountPrefix = cfg->useMountPrefix; + } } std::filesystem::path FileSystemHandler::getInitPath(FileSystemArgsIF* args) { - bool useMountPrefix = true; - parseCfg(reinterpret_cast(args), useMountPrefix); - std::string path; - if(useMountPrefix) { - path = currentMountPrefix; - } - return std::filesystem::path(path); + bool useMountPrefix = true; + parseCfg(reinterpret_cast(args), useMountPrefix); + std::string path; + if (useMountPrefix) { + path = currentMountPrefix; + } + return std::filesystem::path(path); } diff --git a/bsp_q7s/memory/FileSystemHandler.h b/bsp_q7s/memory/FileSystemHandler.h index 35a0f533..282cddba 100644 --- a/bsp_q7s/memory/FileSystemHandler.h +++ b/bsp_q7s/memory/FileSystemHandler.h @@ -1,71 +1,68 @@ #ifndef BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_ #define BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_ -#include "SdCardManager.h" -#include "OBSWConfig.h" - -#include "fsfw/ipc/MessageQueueIF.h" -#include "fsfw/tasks/ExecutableObjectIF.h" -#include "fsfw/objectmanager/SystemObject.h" -#include "fsfw/memory/HasFileSystemIF.h" - -#include #include +#include + +#include "OBSWConfig.h" +#include "SdCardManager.h" +#include "eive/definitions.h" +#include "fsfw/ipc/MessageQueueIF.h" +#include "fsfw/memory/HasFileSystemIF.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/tasks/ExecutableObjectIF.h" class CoreController; -class FileSystemHandler: public SystemObject, - public ExecutableObjectIF, - public HasFileSystemIF { -public: - struct FsCommandCfg: public FileSystemArgsIF { - // Can be used to automatically use mount prefix of active SD card. - // Otherwise, the operator has to specify the full path to the mounted SD card as well. - bool useMountPrefix = false; - }; +class FileSystemHandler : public SystemObject, public ExecutableObjectIF, public HasFileSystemIF { + public: + struct FsCommandCfg : public FileSystemArgsIF { + // Can be used to automatically use mount prefix of active SD card. + // Otherwise, the operator has to specify the full path to the mounted SD card as well. + bool useMountPrefix = false; + }; - FileSystemHandler(object_id_t fileSystemHandler); - virtual~ FileSystemHandler(); + FileSystemHandler(object_id_t fileSystemHandler); + virtual ~FileSystemHandler(); - ReturnValue_t performOperation(uint8_t) override; + ReturnValue_t performOperation(uint8_t) override; - ReturnValue_t initialize() override; + ReturnValue_t initialize() override; - /** - * Function to get the MessageQueueId_t of the implementing object - * @return MessageQueueId_t of the object - */ - MessageQueueId_t getCommandQueue() const override; - ReturnValue_t appendToFile(const char* repositoryPath, - const char* filename, const uint8_t* data, size_t size, - uint16_t packetNumber, FileSystemArgsIF* args = nullptr) override; - ReturnValue_t createFile(const char* repositoryPath, - const char* filename, const uint8_t* data = nullptr, - size_t size = 0, FileSystemArgsIF* args = nullptr) override; - ReturnValue_t removeFile(const char* repositoryPath, - const char* filename, FileSystemArgsIF* args = nullptr) override; - ReturnValue_t createDirectory(const char* repositoryPath, const char* dirname, - bool createParentDirs, FileSystemArgsIF* args = nullptr) override; - ReturnValue_t removeDirectory(const char* repositoryPath, const char* dirname, - bool deleteRecurively = false, FileSystemArgsIF* args = nullptr) override; - ReturnValue_t renameFile(const char* repositoryPath, const char* oldFilename, - const char* newFilename, FileSystemArgsIF* args = nullptr) override; + /** + * Function to get the MessageQueueId_t of the implementing object + * @return MessageQueueId_t of the object + */ + MessageQueueId_t getCommandQueue() const override; + ReturnValue_t appendToFile(const char* repositoryPath, const char* filename, const uint8_t* data, + size_t size, uint16_t packetNumber, + FileSystemArgsIF* args = nullptr) override; + ReturnValue_t createFile(const char* repositoryPath, const char* filename, + const uint8_t* data = nullptr, size_t size = 0, + FileSystemArgsIF* args = nullptr) override; + ReturnValue_t removeFile(const char* repositoryPath, const char* filename, + FileSystemArgsIF* args = nullptr) override; + ReturnValue_t createDirectory(const char* repositoryPath, const char* dirname, + bool createParentDirs, FileSystemArgsIF* args = nullptr) override; + ReturnValue_t removeDirectory(const char* repositoryPath, const char* dirname, + bool deleteRecurively = false, + FileSystemArgsIF* args = nullptr) override; + ReturnValue_t renameFile(const char* repositoryPath, const char* oldFilename, + const char* newFilename, FileSystemArgsIF* args = nullptr) override; -private: - CoreController* coreCtrl = nullptr; - MessageQueueIF* mq = nullptr; - std::string currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; - static constexpr uint32_t FS_MAX_QUEUE_SIZE = config::OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE; + private: + CoreController* coreCtrl = nullptr; + MessageQueueIF* mq = nullptr; + std::string currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; + static constexpr uint32_t FS_MAX_QUEUE_SIZE = config::OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE; - SdCardManager* sdcMan = nullptr; - uint8_t opCounter = 0; + SdCardManager* sdcMan = nullptr; + uint8_t opCounter = 0; - void fileSystemHandlerLoop(); - void fileSystemCheckup(); - std::filesystem::path getInitPath(FileSystemArgsIF* args); - void parseCfg(FsCommandCfg* cfg, bool& useMountPrefix); + void fileSystemHandlerLoop(); + void fileSystemCheckup(); + std::filesystem::path getInitPath(FileSystemArgsIF* args); + void parseCfg(FsCommandCfg* cfg, bool& useMountPrefix); }; - - #endif /* BSP_Q7S_MEMORY_FILESYSTEMMANAGER_H_ */ diff --git a/bsp_q7s/memory/FilesystemHelper.cpp b/bsp_q7s/memory/FilesystemHelper.cpp new file mode 100644 index 00000000..4b9140f1 --- /dev/null +++ b/bsp_q7s/memory/FilesystemHelper.cpp @@ -0,0 +1,40 @@ +#include "FilesystemHelper.h" + +#include +#include + +#include "bsp_q7s/memory/SdCardManager.h" +#include "fsfw/serviceinterface/ServiceInterfaceStream.h" + +FilesystemHelper::FilesystemHelper() {} + +FilesystemHelper::~FilesystemHelper() {} + +ReturnValue_t FilesystemHelper::checkPath(std::string path) { + SdCardManager* sdcMan = SdCardManager::instance(); + if (sdcMan == nullptr) { + sif::warning << "FilesystemHelper::checkPath: Invalid SD card manager" << std::endl; + return RETURN_FAILED; + } + if (path.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT)) == + std::string(SdCardManager::SD_0_MOUNT_POINT)) { + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { + sif::warning << "FilesystemHelper::checkPath: SD card 0 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } else if (path.substr(0, sizeof(SdCardManager::SD_1_MOUNT_POINT)) == + std::string(SdCardManager::SD_1_MOUNT_POINT)) { + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { + sif::warning << "FilesystemHelper::checkPath: SD card 1 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } + return RETURN_OK; +} + +ReturnValue_t FilesystemHelper::fileExists(std::string file) { + if (not std::filesystem::exists(file)) { + return FILE_NOT_EXISTS; + } + return RETURN_OK; +} diff --git a/bsp_q7s/memory/FilesystemHelper.h b/bsp_q7s/memory/FilesystemHelper.h new file mode 100644 index 00000000..cb8e27a8 --- /dev/null +++ b/bsp_q7s/memory/FilesystemHelper.h @@ -0,0 +1,49 @@ +#ifndef BSP_Q7S_MEMORY_FILESYSTEMHELPER_H_ +#define BSP_Q7S_MEMORY_FILESYSTEMHELPER_H_ + +#include + +#include "commonClassIds.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" + +/** + * @brief This class implements often used functions concerning the file system management. + * + * @author J. Meier + */ +class FilesystemHelper : public HasReturnvaluesIF { + public: + static const uint8_t INTERFACE_ID = CLASS_ID::FILE_SYSTEM_HELPER; + + //! [EXPORT] : [COMMENT] SD card specified with path string not mounted + static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Specified file does not exist on filesystem + static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA1); + + FilesystemHelper(); + virtual ~FilesystemHelper(); + + /** + * @brief In case the path points to a directory on the sd card the function checks if the + * appropriate SD card is mounted. + * + * @param path Path to check + * + * @return RETURN_OK if path points to SD card and the appropriate SD card is mounted or if + * path does not point to SD card. + * Return error code if path points to SD card and the corresponding SD card is not + * mounted. + */ + static ReturnValue_t checkPath(std::string path); + + /** + * @brief Checks if the file exists on the filesystem. + * + * param file File to check + * + * @return RETURN_OK if fiel exists, otherwise return error code. + */ + static ReturnValue_t fileExists(std::string file); +}; + +#endif /* BSP_Q7S_MEMORY_FILESYSTEMHELPER_H_ */ diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 8a3d11f2..4ca11787 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -1,487 +1,468 @@ #include "SdCardManager.h" -#include "scratchApi.h" - -#include "linux/utility/utility.h" - -#include "fsfw/ipc/MutexFactory.h" -#include "fsfw/serviceinterface/ServiceInterface.h" +#include +#include #include +#include +#include #include #include -#include -#include + +#include "OBSWConfig.h" +#include "common/config/commonObjects.h" +#include "fsfw/ipc/MutexFactory.h" +#include "fsfw/serviceinterface/ServiceInterface.h" +#include "linux/utility/utility.h" +#include "scratchApi.h" SdCardManager* SdCardManager::factoryInstance = nullptr; -SdCardManager::SdCardManager(): cmdExecutor(256) { +SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor(256) { + mutex = MutexFactory::instance()->createMutex(); } -SdCardManager::~SdCardManager() { -} +SdCardManager::~SdCardManager() {} void SdCardManager::create() { - if(factoryInstance == nullptr) { - factoryInstance = new SdCardManager(); - } + if (factoryInstance == nullptr) { + factoryInstance = new SdCardManager(); + } } SdCardManager* SdCardManager::instance() { - SdCardManager::create(); - return SdCardManager::factoryInstance; + SdCardManager::create(); + return SdCardManager::factoryInstance; } ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard, - SdStatePair* statusPair) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - if(doMountSdCard) { - if(not blocking) { - sif::warning << "SdCardManager::switchOnSdCard: Two-step command but manager is" - " not configured for blocking operation. " - "Forcing blocking mode.." << std::endl; - blocking = true; - } + SdStatePair* statusPair) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if (doMountSdCard) { + if (not blocking) { + sif::warning << "SdCardManager::switchOnSdCard: Two-step command but manager is" + " not configured for blocking operation. " + "Forcing blocking mode.." + << std::endl; + blocking = true; } - std::unique_ptr sdStatusPtr; - if(statusPair == nullptr) { - sdStatusPtr = std::make_unique(); - statusPair = sdStatusPtr.get(); - result = getSdCardActiveStatus(*statusPair); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + } + std::unique_ptr sdStatusPtr; + if (statusPair == nullptr) { + sdStatusPtr = std::make_unique(); + statusPair = sdStatusPtr.get(); + result = getSdCardActiveStatus(*statusPair); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; } + } - // Not allowed, this function turns on one SD card - if(sdCard == sd::SdCard::BOTH) { - sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH" - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } + // Not allowed, this function turns on one SD card + if (sdCard == sd::SdCard::BOTH) { + sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } - sd::SdState currentState; - if(sdCard == sd::SdCard::SLOT_0) { - currentState = statusPair->first; - } - else if(sdCard == sd::SdCard::SLOT_1) { - currentState = statusPair->second; - } - else { - // Should not happen - currentState = sd::SdState::OFF; - } + sd::SdState currentState; + if (sdCard == sd::SdCard::SLOT_0) { + currentState = statusPair->first; + } else if (sdCard == sd::SdCard::SLOT_1) { + currentState = statusPair->second; + } else { + // Should not happen + currentState = sd::SdState::OFF; + } - if(currentState == sd::SdState::ON) { - if(not doMountSdCard) { - return ALREADY_ON; - } - else { - return mountSdCard(sdCard); - } - } - else if(currentState == sd::SdState::MOUNTED) { - result = ALREADY_MOUNTED; - } - else if(currentState == sd::SdState::OFF) { - result = setSdCardState(sdCard, true); - } - else { - result = HasReturnvaluesIF::RETURN_FAILED; + if (currentState == sd::SdState::ON) { + if (not doMountSdCard) { + return ALREADY_ON; + } else { + return mountSdCard(sdCard); } + } else if (currentState == sd::SdState::MOUNTED) { + result = ALREADY_MOUNTED; + } else if (currentState == sd::SdState::OFF) { + result = setSdCardState(sdCard, true); + } else { + result = HasReturnvaluesIF::RETURN_FAILED; + } - if(result != HasReturnvaluesIF::RETURN_OK or not doMountSdCard) { - return result; - } + if (result != HasReturnvaluesIF::RETURN_OK or not doMountSdCard) { + return result; + } - return mountSdCard(sdCard); + return mountSdCard(sdCard); } ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard, - SdStatePair* statusPair) { - std::pair active; - ReturnValue_t result = getSdCardActiveStatus(active); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; + SdStatePair* statusPair) { + std::pair active; + ReturnValue_t result = getSdCardActiveStatus(active); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + if (doUnmountSdCard) { + if (not blocking) { + sif::warning << "SdCardManager::switchOffSdCard: Two-step command but manager is" + " not configured for blocking operation. Forcing blocking mode.." + << std::endl; + blocking = true; } - if(doUnmountSdCard) { - if(not blocking) { - sif::warning << "SdCardManager::switchOffSdCard: Two-step command but manager is" - " not configured for blocking operation. Forcing blocking mode.." << std::endl; - blocking = true; - } + } + // Not allowed, this function turns off one SD card + if (sdCard == sd::SdCard::BOTH) { + sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + if (sdCard == sd::SdCard::SLOT_0) { + if (active.first == sd::SdState::OFF) { + return ALREADY_OFF; } - // Not allowed, this function turns off one SD card - if(sdCard == sd::SdCard::BOTH) { - sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH" - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - if(sdCard == sd::SdCard::SLOT_0) { - if(active.first == sd::SdState::OFF) { - return ALREADY_OFF; - } - } - else if(sdCard == sd::SdCard::SLOT_1) { - if(active.second == sd::SdState::OFF) { - return ALREADY_OFF; - } + } else if (sdCard == sd::SdCard::SLOT_1) { + if (active.second == sd::SdState::OFF) { + return ALREADY_OFF; } + } - if(doUnmountSdCard) { - result = unmountSdCard(sdCard); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + if (doUnmountSdCard) { + result = unmountSdCard(sdCard); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; } + } - return setSdCardState(sdCard, false); + return setSdCardState(sdCard, false); } ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { - using namespace std; - if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { - return CommandExecutor::COMMAND_PENDING; - } - string sdstring = ""; - string statestring = ""; - if(sdCard == sd::SdCard::SLOT_0) { - sdstring = "0"; - } - else if(sdCard == sd::SdCard::SLOT_1) { - sdstring = "1"; - } - if(on) { - currentOp = Operations::SWITCHING_ON; - statestring = "on"; - } - else { - currentOp = Operations::SWITCHING_OFF; - statestring = "off"; - } - ostringstream command; - command << "q7hw sd set " << sdstring << " " << statestring; - cmdExecutor.load(command.str(), blocking, printCmdOutput); - ReturnValue_t result = cmdExecutor.execute(); - if(blocking and result != HasReturnvaluesIF::RETURN_OK) { - utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::setSdCardState"); - } - return result; + using namespace std; + if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; + } + string sdstring = ""; + string statestring = ""; + if (sdCard == sd::SdCard::SLOT_0) { + sdstring = "0"; + } else if (sdCard == sd::SdCard::SLOT_1) { + sdstring = "1"; + } + if (on) { + currentOp = Operations::SWITCHING_ON; + statestring = "on"; + } else { + currentOp = Operations::SWITCHING_OFF; + statestring = "off"; + } + ostringstream command; + command << "q7hw sd set " << sdstring << " " << statestring; + cmdExecutor.load(command.str(), blocking, printCmdOutput); + ReturnValue_t result = cmdExecutor.execute(); + if (blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::setSdCardState"); + } + return result; } ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatePair& active) { - using namespace std; - if(not filesystem::exists(SD_STATE_FILE)) { - return STATUS_FILE_NEXISTS; - } + using namespace std; + MutexGuard mg(mutex); + if (not filesystem::exists(SD_STATE_FILE)) { + return STATUS_FILE_NEXISTS; + } - // Now the file should exist in any case. Still check whether it exists. - fstream sdStatus(SD_STATE_FILE); - if (not sdStatus.good()) { - return STATUS_FILE_NEXISTS; - } - string line; - uint8_t idx = 0; - sd::SdCard currentSd = sd::SdCard::SLOT_0; - // Process status file line by line - while (std::getline(sdStatus, line)) { - processSdStatusLine(active, line, idx, currentSd); - } - return HasReturnvaluesIF::RETURN_OK; + // Now the file should exist in any case. Still check whether it exists. + fstream sdStatus(SD_STATE_FILE); + if (not sdStatus.good()) { + return STATUS_FILE_NEXISTS; + } + string line; + uint8_t idx = 0; + sd::SdCard currentSd = sd::SdCard::SLOT_0; + // Process status file line by line + while (std::getline(sdStatus, line)) { + processSdStatusLine(active, line, idx, currentSd); + } + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { - using namespace std; - if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { - return CommandExecutor::COMMAND_PENDING; - } - if(sdCard == sd::SdCard::BOTH) { - sif::warning << "SdCardManager::mountSdCard: API does not allow sd::SdStatus::BOTH" - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - string mountDev; - string mountPoint; - if(sdCard == sd::SdCard::SLOT_0) { - mountDev = SD_0_DEV_NAME; - mountPoint = SD_0_MOUNT_POINT; - } - else if(sdCard == sd::SdCard::SLOT_1) { - mountDev = SD_1_DEV_NAME; - mountPoint = SD_1_MOUNT_POINT; - } - if(not filesystem::exists(mountDev)) { - sif::warning << "SdCardManager::mountSdCard: Device file does not exists. Make sure to" - " turn on the SD card" << std::endl; - return MOUNT_ERROR; - } + using namespace std; + if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; + } + if (sdCard == sd::SdCard::BOTH) { + sif::warning << "SdCardManager::mountSdCard: API does not allow sd::SdStatus::BOTH" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + string mountDev; + string mountPoint; + if (sdCard == sd::SdCard::SLOT_0) { + mountDev = SD_0_DEV_NAME; + mountPoint = SD_0_MOUNT_POINT; + } else if (sdCard == sd::SdCard::SLOT_1) { + mountDev = SD_1_DEV_NAME; + mountPoint = SD_1_MOUNT_POINT; + } + if (not filesystem::exists(mountDev)) { + sif::warning << "SdCardManager::mountSdCard: Device file does not exists. Make sure to" + " turn on the SD card" + << std::endl; + return MOUNT_ERROR; + } - if(not blocking) { - currentOp = Operations::MOUNTING; - } - string sdMountCommand = "mount " + mountDev + " " + mountPoint; - cmdExecutor.load(sdMountCommand, blocking, printCmdOutput); - ReturnValue_t result = cmdExecutor.execute(); - if(blocking and result != HasReturnvaluesIF::RETURN_OK) { - utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); - } - return result; + if (not blocking) { + currentOp = Operations::MOUNTING; + } + string sdMountCommand = "mount " + mountDev + " " + mountPoint; + cmdExecutor.load(sdMountCommand, blocking, printCmdOutput); + ReturnValue_t result = cmdExecutor.execute(); + if (blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); + } + return result; } ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { - if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { - return CommandExecutor::COMMAND_PENDING; - } - using namespace std; - if(sdCard == sd::SdCard::BOTH) { - sif::warning << "SdCardManager::unmountSdCard: API does not allow sd::SdStatus::BOTH" - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - string mountPoint; - if(sdCard == sd::SdCard::SLOT_0) { - mountPoint = SD_0_MOUNT_POINT; - } - else if(sdCard == sd::SdCard::SLOT_1) { - mountPoint = SD_1_MOUNT_POINT; - } - if(not filesystem::exists(mountPoint)) { - sif::error << "SdCardManager::unmountSdCard: Default mount point " << mountPoint << - "does not exist" << std::endl; - return UNMOUNT_ERROR; - } - if(filesystem::is_empty(mountPoint)) { - // The mount point will always exist, but if it is empty, that is strong hint that - // the SD card was not mounted properly. Still proceed with operation. - sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl; - } - string sdUnmountCommand = "umount " + mountPoint; - if(not blocking) { - currentOp = Operations::UNMOUNTING; - } - cmdExecutor.load(sdUnmountCommand, blocking, printCmdOutput); - ReturnValue_t result = cmdExecutor.execute(); - if(blocking and result != HasReturnvaluesIF::RETURN_OK) { - utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::unmountSdCard"); - } - return result; + if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; + } + using namespace std; + if (sdCard == sd::SdCard::BOTH) { + sif::warning << "SdCardManager::unmountSdCard: API does not allow sd::SdStatus::BOTH" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + string mountPoint; + if (sdCard == sd::SdCard::SLOT_0) { + mountPoint = SD_0_MOUNT_POINT; + } else if (sdCard == sd::SdCard::SLOT_1) { + mountPoint = SD_1_MOUNT_POINT; + } + if (not filesystem::exists(mountPoint)) { + sif::error << "SdCardManager::unmountSdCard: Default mount point " << mountPoint + << "does not exist" << std::endl; + return UNMOUNT_ERROR; + } + if (filesystem::is_empty(mountPoint)) { + // The mount point will always exist, but if it is empty, that is strong hint that + // the SD card was not mounted properly. Still proceed with operation. + sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl; + } + string sdUnmountCommand = "umount " + mountPoint; + if (not blocking) { + currentOp = Operations::UNMOUNTING; + } + cmdExecutor.load(sdUnmountCommand, blocking, printCmdOutput); + ReturnValue_t result = cmdExecutor.execute(); + if (blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::unmountSdCard"); + } + return result; } ReturnValue_t SdCardManager::sanitizeState(SdStatePair* statusPair, sd::SdCard prefSdCard) { - std::unique_ptr sdStatusPtr; - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - // Enforce blocking operation for now. Be careful to reset it when returning prematurely! - bool resetNonBlockingState = false; - if(not this->blocking) { - blocking = true; - resetNonBlockingState = true; - } - if(prefSdCard == sd::SdCard::NONE) { - result = getPreferredSdCard(prefSdCard); - if(result != HasReturnvaluesIF::RETURN_OK) {} - } - if(statusPair == nullptr) { - sdStatusPtr = std::make_unique(); - statusPair = sdStatusPtr.get(); - getSdCardActiveStatus(*statusPair); + std::unique_ptr sdStatusPtr; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + // Enforce blocking operation for now. Be careful to reset it when returning prematurely! + bool resetNonBlockingState = false; + if (not this->blocking) { + blocking = true; + resetNonBlockingState = true; + } + if (prefSdCard == sd::SdCard::NONE) { + result = getPreferredSdCard(prefSdCard); + if (result != HasReturnvaluesIF::RETURN_OK) { } + } + if (statusPair == nullptr) { + sdStatusPtr = std::make_unique(); + statusPair = sdStatusPtr.get(); + getSdCardActiveStatus(*statusPair); + } - if(statusPair->first == sd::SdState::ON) { - result = mountSdCard(prefSdCard); - } + if (statusPair->first == sd::SdState::ON) { + result = mountSdCard(prefSdCard); + } - result = switchOnSdCard(prefSdCard, true, statusPair); - if(resetNonBlockingState) { - blocking = false; - } - return result; + result = switchOnSdCard(prefSdCard, true, statusPair); + if (resetNonBlockingState) { + blocking = false; + } + return result; } void SdCardManager::resetState() { - cmdExecutor.reset(); - currentOp = Operations::IDLE; + cmdExecutor.reset(); + currentOp = Operations::IDLE; } -void SdCardManager::processSdStatusLine(std::pair &active, - std::string& line, uint8_t& idx, sd::SdCard& currentSd) { - using namespace std; - istringstream iss(line); - string word; - bool slotLine = false; - bool mountLine = false; - while(iss >> word) { - if (word == "Slot") { - slotLine = true; - } - if(word == "Mounted") { - mountLine = true; - } - - if(slotLine) { - if (word == "1:") { - currentSd = sd::SdCard::SLOT_1; - } - - if(word == "on") { - if(currentSd == sd::SdCard::SLOT_0) { - active.first = sd::SdState::ON; - } - else { - active.second = sd::SdState::ON; - } - } - else if (word == "off") { - if(currentSd == sd::SdCard::SLOT_0) { - active.first = sd::SdState::OFF; - } - else { - active.second = sd::SdState::OFF; - } - } - } - - if(mountLine) { - if(currentSd == sd::SdCard::SLOT_0) { - active.first = sd::SdState::MOUNTED; - } - else { - active.second = sd::SdState::MOUNTED; - } - } - - if(idx > 5) { - sif::warning << "SdCardManager::sdCardActive: /tmp/sd_status.txt has more than 6 " - "lines and might be invalid!" << std::endl; - } +void SdCardManager::processSdStatusLine(std::pair& active, + std::string& line, uint8_t& idx, sd::SdCard& currentSd) { + using namespace std; + istringstream iss(line); + string word; + bool slotLine = false; + bool mountLine = false; + while (iss >> word) { + if (word == "Slot") { + slotLine = true; } - idx++; + if (word == "Mounted") { + mountLine = true; + } + + if (slotLine) { + if (word == "1:") { + currentSd = sd::SdCard::SLOT_1; + } + + if (word == "on") { + if (currentSd == sd::SdCard::SLOT_0) { + active.first = sd::SdState::ON; + } else { + active.second = sd::SdState::ON; + } + } else if (word == "off") { + if (currentSd == sd::SdCard::SLOT_0) { + active.first = sd::SdState::OFF; + } else { + active.second = sd::SdState::OFF; + } + } + } + + if (mountLine) { + if (currentSd == sd::SdCard::SLOT_0) { + active.first = sd::SdState::MOUNTED; + } else { + active.second = sd::SdState::MOUNTED; + } + } + + if (idx > 5) { + sif::warning << "SdCardManager::sdCardActive: /tmp/sd_status.txt has more than 6 " + "lines and might be invalid!" + << std::endl; + } + } + idx++; } ReturnValue_t SdCardManager::getPreferredSdCard(sd::SdCard& sdCard) const { - uint8_t prefSdCard = 0; - ReturnValue_t result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdCard); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - sdCard = static_cast(prefSdCard); - return HasReturnvaluesIF::RETURN_OK; + uint8_t prefSdCard = 0; + ReturnValue_t result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdCard); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + sdCard = static_cast(prefSdCard); + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) { - if(sdCard == sd::SdCard::BOTH) { - return HasReturnvaluesIF::RETURN_FAILED; - } - return scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast(sdCard)); + if (sdCard == sd::SdCard::BOTH) { + return HasReturnvaluesIF::RETURN_FAILED; + } + return scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast(sdCard)); } ReturnValue_t SdCardManager::updateSdCardStateFile() { - if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { - return CommandExecutor::COMMAND_PENDING; - } - // Use q7hw utility and pipe the command output into the state file - std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE); - cmdExecutor.load(updateCmd, blocking, printCmdOutput); - ReturnValue_t result = cmdExecutor.execute(); - if(blocking and result != HasReturnvaluesIF::RETURN_OK) { - utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); - } - return result; + if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; + } + MutexGuard mg(mutex); + // Use q7hw utility and pipe the command output into the state file + std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE); + cmdExecutor.load(updateCmd, blocking, printCmdOutput); + ReturnValue_t result = cmdExecutor.execute(); + if (blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); + } + return result; } std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) { - if(prefSdCard == sd::SdCard::NONE) { - ReturnValue_t result = getPreferredSdCard(prefSdCard); - if(result != HasReturnvaluesIF::RETURN_OK) { - return SD_0_MOUNT_POINT; - } - } - if(prefSdCard == sd::SdCard::SLOT_0) { - return SD_0_MOUNT_POINT; - } - else { - return SD_1_MOUNT_POINT; + if (prefSdCard == sd::SdCard::NONE) { + ReturnValue_t result = getPreferredSdCard(prefSdCard); + if (result != HasReturnvaluesIF::RETURN_OK) { + return SD_0_MOUNT_POINT; } + } + if (prefSdCard == sd::SdCard::SLOT_0) { + return SD_0_MOUNT_POINT; + } else { + return SD_1_MOUNT_POINT; + } } -SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) { - CommandExecutor::States state = cmdExecutor.getCurrentState(); - if(state == CommandExecutor::States::IDLE or state == CommandExecutor::States::COMMAND_LOADED) { - return OpStatus::IDLE; - } - currentOp = this->currentOp; - bool bytesRead = false; +SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations& currentOp) { + CommandExecutor::States state = cmdExecutor.getCurrentState(); + if (state == CommandExecutor::States::IDLE or state == CommandExecutor::States::COMMAND_LOADED) { + return OpStatus::IDLE; + } + currentOp = this->currentOp; + bool bytesRead = false; #if OBSW_ENABLE_TIMERS == 1 - Timer timer; - timer.setTimer(100); - uint32_t remainingTimeMs = 0; + Countdown timer(1000); #endif - while(true) { - ReturnValue_t result = cmdExecutor.check(bytesRead); - // This timer can prevent deadlocks due to missconfigurations + while (true) { + ReturnValue_t result = cmdExecutor.check(bytesRead); + // This timer can prevent deadlocks due to missconfigurations #if OBSW_ENABLE_TIMERS == 1 - timer.getTimer(&remainingTimeMs); - if(remainingTimeMs == 0) { - sif::error << "SdCardManager::checkCurrentOp: Timeout!" << std::endl; - return OpStatus::FAIL; - } -#endif - switch(result) { - case(CommandExecutor::BYTES_READ): { - continue; - } - case(CommandExecutor::EXECUTION_FINISHED): { - return OpStatus::SUCCESS; - } - case(HasReturnvaluesIF::RETURN_OK): { - return OpStatus::ONGOING; - } - case(HasReturnvaluesIF::RETURN_FAILED): { - return OpStatus::FAIL; - } - default: { - sif::warning << "SdCardManager::checkCurrentOp: Unhandled case" << std::endl; - } - } + if (timer.hasTimedOut()) { + sif::error << "SdCardManager::checkCurrentOp: Timeout!" << std::endl; + return OpStatus::FAIL; } +#endif + switch (result) { + case (CommandExecutor::BYTES_READ): { + continue; + } + case (CommandExecutor::EXECUTION_FINISHED): { + return OpStatus::SUCCESS; + } + case (HasReturnvaluesIF::RETURN_OK): { + return OpStatus::ONGOING; + } + case (HasReturnvaluesIF::RETURN_FAILED): { + return OpStatus::FAIL; + } + default: { + sif::warning << "SdCardManager::checkCurrentOp: Unhandled case" << std::endl; + } + } + } } -void SdCardManager::setBlocking(bool blocking) { - this->blocking = blocking; -} +void SdCardManager::setBlocking(bool blocking) { this->blocking = blocking; } -void SdCardManager::setPrintCommandOutput(bool print) { - this->printCmdOutput = print; - -} +void SdCardManager::setPrintCommandOutput(bool print) { this->printCmdOutput = print; } bool SdCardManager::isSdCardMounted(sd::SdCard sdCard) { - SdCardManager::SdStatePair active; - ReturnValue_t result = this->getSdCardActiveStatus(active); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state"; - return false; - } - if (sdCard == sd::SLOT_0) { - if (active.first == sd::MOUNTED) { - return true; - } - else { - return false; - } - } - else if (sdCard == sd::SLOT_1) { - if (active.second == sd::MOUNTED) { - return true; - } - else { - return false; - } - } - else { - sif::debug << "SdCardManager::isSdCardMounted: Unknown SD card specified" << std::endl; - } + SdCardManager::SdStatePair active; + ReturnValue_t result = this->getSdCardActiveStatus(active); + + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state"; return false; + } + if (sdCard == sd::SLOT_0) { + if (active.first == sd::MOUNTED) { + return true; + } else { + return false; + } + } else if (sdCard == sd::SLOT_1) { + if (active.second == sd::MOUNTED) { + return true; + } else { + return false; + } + } else { + sif::debug << "SdCardManager::isSdCardMounted: Unknown SD card specified" << std::endl; + } + return false; } - - diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 6e4930da..37660f75 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -1,21 +1,22 @@ #ifndef BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ #define BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ -#include "fsfw_hal/linux/CommandExecutor.h" -#include "definitions.h" -#include "returnvalues/classIds.h" -#include "events/subsystemIdRanges.h" - -#include "fsfw/events/Event.h" -#include "fsfw/returnvalues/HasReturnvaluesIF.h" - +#include #include -#include -#include -#include -#include #include +#include +#include +#include +#include + +#include "events/subsystemIdRanges.h" +#include "fsfw/events/Event.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw_hal/linux/CommandExecutor.h" +#include "mission/memory/SdCardMountedIF.h" +#include "mission/memory/definitions.h" +#include "returnvalues/classIds.h" class MutexIF; @@ -23,203 +24,193 @@ class MutexIF; * @brief Manages handling of SD cards like switching them on or off or getting the current * state */ -class SdCardManager { - friend class SdCardAccess; -public: - enum class Operations { - SWITCHING_ON, - SWITCHING_OFF, - MOUNTING, - UNMOUNTING, - IDLE - }; +class SdCardManager : public SystemObject, public SdCardMountedIF { + friend class SdCardAccess; - enum class OpStatus { - IDLE, - TIMEOUT, - ONGOING, - SUCCESS, - FAIL - }; + public: + using mountInitCb = ReturnValue_t (*)(void* args); - using SdStatePair = std::pair; + enum class Operations { SWITCHING_ON, SWITCHING_OFF, MOUNTING, UNMOUNTING, IDLE }; - static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER; + enum class OpStatus { IDLE, TIMEOUT, ONGOING, SUCCESS, FAIL }; - static constexpr ReturnValue_t OP_ONGOING = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 0); - static constexpr ReturnValue_t ALREADY_ON = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1); - static constexpr ReturnValue_t ALREADY_MOUNTED = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 2); - static constexpr ReturnValue_t ALREADY_OFF = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 3); - static constexpr ReturnValue_t STATUS_FILE_NEXISTS = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 10); - static constexpr ReturnValue_t STATUS_FILE_FORMAT_INVALID = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 11); - static constexpr ReturnValue_t MOUNT_ERROR = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 12); - static constexpr ReturnValue_t UNMOUNT_ERROR = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 13); - static constexpr ReturnValue_t SYSTEM_CALL_ERROR = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 14); - static constexpr ReturnValue_t POPEN_CALL_ERROR = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 15); + using SdStatePair = std::pair; - static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FILE_SYSTEM; + static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER; - static constexpr Event SANITIZATION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); + static constexpr ReturnValue_t OP_ONGOING = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 0); + static constexpr ReturnValue_t ALREADY_ON = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1); + static constexpr ReturnValue_t ALREADY_MOUNTED = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 2); + static constexpr ReturnValue_t ALREADY_OFF = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 3); + static constexpr ReturnValue_t STATUS_FILE_NEXISTS = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 10); + static constexpr ReturnValue_t STATUS_FILE_FORMAT_INVALID = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 11); + static constexpr ReturnValue_t MOUNT_ERROR = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 12); + static constexpr ReturnValue_t UNMOUNT_ERROR = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 13); + static constexpr ReturnValue_t SYSTEM_CALL_ERROR = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 14); + static constexpr ReturnValue_t POPEN_CALL_ERROR = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 15); - // C++17 does not support constexpr std::string yet - static constexpr char SD_0_DEV_NAME[] = "/dev/mmcblk0p1"; - static constexpr char SD_1_DEV_NAME[] = "/dev/mmcblk1p1"; - static constexpr char SD_0_MOUNT_POINT[] = "/mnt/sd0"; - static constexpr char SD_1_MOUNT_POINT[] = "/mnt/sd1"; - static constexpr char SD_STATE_FILE[] = "/tmp/sd_status.txt"; + static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FILE_SYSTEM; - virtual ~SdCardManager(); + static constexpr Event SANITIZATION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); + static constexpr Event MOUNTED_SD_CARD = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO); - static void create(); + // C++17 does not support constexpr std::string yet + static constexpr char SD_0_DEV_NAME[] = "/dev/mmcblk0p1"; + static constexpr char SD_1_DEV_NAME[] = "/dev/mmcblk1p1"; + static constexpr char SD_0_MOUNT_POINT[] = "/mnt/sd0"; + static constexpr char SD_1_MOUNT_POINT[] = "/mnt/sd1"; + static constexpr char SD_STATE_FILE[] = "/tmp/sd_status.txt"; - /** - * Returns the single instance of the SD card manager. - */ - static SdCardManager* instance(); + virtual ~SdCardManager(); - /** - * Set the preferred SD card which will determine which SD card will be used as the primary - * SD card in hot redundant and cold redundant mode. This function will not switch the - * SD cards which are currently on and mounted, this needs to be implemented by - * an upper layer by using #switchOffSdCard , #switchOnSdCard and #updateSdCardStateFile - * @param sdCard - * @return - */ - ReturnValue_t setPreferredSdCard(sd::SdCard sdCard); + static void create(); - /** - * Get the currently configured preferred SD card - * @param sdCard - * @return - */ - ReturnValue_t getPreferredSdCard(sd::SdCard& sdCard) const; + /** + * Returns the single instance of the SD card manager. + */ + static SdCardManager* instance(); - /** - * Switch on the specified SD card. - * @param sdCard - * @param doMountSdCard Mount the SD card after switching it on, which is necessary - * to use it - * @param statusPair If the status pair is already available, it can be passed here - * @return - RETURN_OK on success, ALREADY_ON if it is already on, - * SYSTEM_CALL_ERROR on system error - */ - ReturnValue_t switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard = true, - SdStatePair* statusPair = nullptr); + /** + * Set the preferred SD card which will determine which SD card will be used as the primary + * SD card in hot redundant and cold redundant mode. This function will not switch the + * SD cards which are currently on and mounted, this needs to be implemented by + * an upper layer by using #switchOffSdCard , #switchOnSdCard and #updateSdCardStateFile + * @param sdCard + * @return + */ + ReturnValue_t setPreferredSdCard(sd::SdCard sdCard); - /** - * Switch off the specified SD card. - * @param sdCard - * @param doUnmountSdCard Unmount the SD card before switching the card off, which makes - * the operation safer - * @param statusPair If the status pair is already available, it can be passed here - * @return - RETURN_OK on success, ALREADY_ON if it is already on, - * SYSTEM_CALL_ERROR on system error - */ - ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true, - SdStatePair* statusPair = nullptr); + /** + * Get the currently configured preferred SD card + * @param sdCard + * @return + */ + ReturnValue_t getPreferredSdCard(sd::SdCard& sdCard) const override; - /** - * Update the state file or creates one if it does not exist. You need to call this - * function before calling #sdCardActive - * @return - * - RETURN_OK if the state file was updated successfully - * - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending - * - RETURN_FAILED: blocking command failed - */ - ReturnValue_t updateSdCardStateFile(); + /** + * Switch on the specified SD card. + * @param sdCard + * @param doMountSdCard Mount the SD card after switching it on, which is necessary + * to use it + * @param statusPair If the status pair is already available, it can be passed here + * @return - RETURN_OK on success, ALREADY_ON if it is already on, + * SYSTEM_CALL_ERROR on system error + */ + ReturnValue_t switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard = true, + SdStatePair* statusPair = nullptr); - /** - * Get the state of the SD cards. If the state file does not exist, this function will - * take care of updating it. If it does not, the function will use the state file to get - * the status of the SD cards and set the field of the provided boolean pair. - * @param active Pair of booleans, where the first entry is the state of the first SD card - * and the second one the state of the second SD card - * @return - RETURN_OK if the state was read successfully - * - STATUS_FILE_FORMAT_INVALID if there was an issue with the state file. The user - * should call #updateSdCardStateFile again in that case - * - STATUS_FILE_NEXISTS if the status file does not exist - */ - ReturnValue_t getSdCardActiveStatus(SdStatePair& active); + /** + * Switch off the specified SD card. + * @param sdCard + * @param doUnmountSdCard Unmount the SD card before switching the card off, which makes + * the operation safer + * @param statusPair If the status pair is already available, it can be passed here + * @return - RETURN_OK on success, ALREADY_ON if it is already on, + * SYSTEM_CALL_ERROR on system error + */ + ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true, + SdStatePair* statusPair = nullptr); - /** - * Mount the specified SD card. This is necessary to use it. - * @param sdCard - * @return - */ - ReturnValue_t mountSdCard(sd::SdCard sdCard); - /** - * Unmount the specified SD card. This is recommended before switching it off. The SD card - * can't be used after it has been unmounted. - * @param sdCard - * @return - */ - ReturnValue_t unmountSdCard(sd::SdCard sdCard); + /** + * Update the state file or creates one if it does not exist. You need to call this + * function before calling #sdCardActive + * @return + * - RETURN_OK if the state file was updated successfully + * - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending + * - RETURN_FAILED: blocking command failed + */ + ReturnValue_t updateSdCardStateFile(); - /** - * In case that there is a discrepancy between the preferred SD card and the currently - * mounted one, this function will sanitize the state by attempting to mount the - * currently preferred SD card. If the caller already has state information, it can be - * passed into the function. For now, this operation will be enforced in blocking mode. - * @param statusPair Current SD card status capture with #getSdCardActiveStatus - * @param prefSdCard Preferred SD card captured with #getPreferredSdCard - * @throws std::bad_alloc if one of the two arguments was a nullptr and an allocation failed - * @return - */ - ReturnValue_t sanitizeState(SdStatePair* statusPair = nullptr, - sd::SdCard prefSdCard = sd::SdCard::NONE); + /** + * Get the state of the SD cards. If the state file does not exist, this function will + * take care of updating it. If it does not, the function will use the state file to get + * the status of the SD cards and set the field of the provided boolean pair. + * @param active Pair of booleans, where the first entry is the state of the first SD card + * and the second one the state of the second SD card + * @return - RETURN_OK if the state was read successfully + * - STATUS_FILE_FORMAT_INVALID if there was an issue with the state file. The user + * should call #updateSdCardStateFile again in that case + * - STATUS_FILE_NEXISTS if the status file does not exist + */ + ReturnValue_t getSdCardActiveStatus(SdStatePair& active); - /** - * If sd::SdCard::NONE is passed as an argument, this function will get the currently - * preferred SD card from the scratch buffer. - * @param prefSdCardPtr - * @return - */ - std::string getCurrentMountPrefix(sd::SdCard prefSdCardPtr = sd::SdCard::NONE); + /** + * Mount the specified SD card. This is necessary to use it. + * @param sdCard + * @return + */ + ReturnValue_t mountSdCard(sd::SdCard sdCard); + /** + * Unmount the specified SD card. This is recommended before switching it off. The SD card + * can't be used after it has been unmounted. + * @param sdCard + * @return + */ + ReturnValue_t unmountSdCard(sd::SdCard sdCard); - OpStatus checkCurrentOp(Operations& currentOp); + /** + * In case that there is a discrepancy between the preferred SD card and the currently + * mounted one, this function will sanitize the state by attempting to mount the + * currently preferred SD card. If the caller already has state information, it can be + * passed into the function. For now, this operation will be enforced in blocking mode. + * @param statusPair Current SD card status capture with #getSdCardActiveStatus + * @param prefSdCard Preferred SD card captured with #getPreferredSdCard + * @throws std::bad_alloc if one of the two arguments was a nullptr and an allocation failed + * @return + */ + ReturnValue_t sanitizeState(SdStatePair* statusPair = nullptr, + sd::SdCard prefSdCard = sd::SdCard::NONE); - /** - * If there are issues with the state machine, it can be reset with this function - */ - void resetState(); + /** + * If sd::SdCard::NONE is passed as an argument, this function will get the currently + * preferred SD card from the scratch buffer. + * @param prefSdCardPtr + * @return + */ + std::string getCurrentMountPrefix(sd::SdCard prefSdCardPtr = sd::SdCard::NONE) override; - void setBlocking(bool blocking); - void setPrintCommandOutput(bool print); + OpStatus checkCurrentOp(Operations& currentOp); - /** - * @brief Checks if an SD card is mounted - * - * @param sdCard The SD crad to check - * - * @return true if mounted, otherwise false - */ - bool isSdCardMounted(sd::SdCard sdCard); -private: - CommandExecutor cmdExecutor; - Operations currentOp = Operations::IDLE; - bool blocking = false; - bool printCmdOutput = true; + /** + * If there are issues with the state machine, it can be reset with this function + */ + void resetState(); - SdCardManager(); + void setBlocking(bool blocking); + void setPrintCommandOutput(bool print); - ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on); + /** + * @brief Checks if an SD card is mounted. + * + * @param sdCard The SD card to check + * + * @return true if mounted, otherwise false + */ + bool isSdCardMounted(sd::SdCard sdCard) override; - void processSdStatusLine(SdStatePair& active, std::string& line, uint8_t& idx, - sd::SdCard& currentSd); + private: + CommandExecutor cmdExecutor; + Operations currentOp = Operations::IDLE; + bool blocking = false; + bool printCmdOutput = true; + MutexIF* mutex = nullptr; - std::string currentPrefix; + SdCardManager(); - static SdCardManager* factoryInstance; + ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on); + + void processSdStatusLine(SdStatePair& active, std::string& line, uint8_t& idx, + sd::SdCard& currentSd); + + std::string currentPrefix; + + static SdCardManager* factoryInstance; }; #endif /* BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ */ diff --git a/bsp_q7s/memory/definitions.h b/bsp_q7s/memory/definitions.h deleted file mode 100644 index 9e0bca65..00000000 --- a/bsp_q7s/memory/definitions.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef BSP_Q7S_MEMORY_DEFINITIONS_H_ -#define BSP_Q7S_MEMORY_DEFINITIONS_H_ - -#include - -namespace sd { - -enum SdState: uint8_t { - OFF = 0, - ON = 1, - // A mounted SD card is on as well - MOUNTED = 2 -}; - -enum SdCard: uint8_t { - SLOT_0 = 0, - SLOT_1 = 1, - BOTH, - NONE -}; - -} - - - -#endif /* BSP_Q7S_MEMORY_DEFINITIONS_H_ */ diff --git a/bsp_q7s/memory/scratchApi.cpp b/bsp_q7s/memory/scratchApi.cpp index 08d59df1..83bc8239 100644 --- a/bsp_q7s/memory/scratchApi.cpp +++ b/bsp_q7s/memory/scratchApi.cpp @@ -1,49 +1,50 @@ #include "scratchApi.h" ReturnValue_t scratch::writeString(std::string name, std::string string) { - std::ostringstream oss; - oss << "xsc_scratch write " << name << " \"" << string << "\""; - int result = std::system(oss.str().c_str()); - if(result != 0) { - utility::handleSystemError(result, "scratch::writeString"); - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; + std::ostringstream oss; + oss << "xsc_scratch write " << name << " \"" << string << "\""; + int result = std::system(oss.str().c_str()); + if (result != 0) { + utility::handleSystemError(result, "scratch::writeString"); + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t scratch::readString(std::string key, std::string &string) { - std::ifstream file; - std::string filename; - ReturnValue_t result = readToFile(key, file, filename); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + std::ifstream file; + std::string filename; + ReturnValue_t result = readToFile(key, file, filename); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - std::string line; - if (not std::getline(file, line)) { - std::remove(filename.c_str()); - return HasReturnvaluesIF::RETURN_FAILED; - } + std::string line; + if (not std::getline(file, line)) { + std::remove(filename.c_str()); + return HasReturnvaluesIF::RETURN_FAILED; + } - size_t pos = line.find("="); - if(pos == std::string::npos) { - sif::warning << "scratch::readNumber: Output file format invalid, " - "no \"=\" found" << std::endl; - // Could not find value - std::remove(filename.c_str()); - return KEY_NOT_FOUND; - } - string = line.substr(pos + 1); - return HasReturnvaluesIF::RETURN_OK; + size_t pos = line.find("="); + if (pos == std::string::npos) { + sif::warning << "scratch::readNumber: Output file format invalid, " + "no \"=\" found" + << std::endl; + // Could not find value + std::remove(filename.c_str()); + return KEY_NOT_FOUND; + } + string = line.substr(pos + 1); + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t scratch::clearValue(std::string key) { - std::ostringstream oss; - oss << "xsc_scratch clear " << key; - int result = std::system(oss.str().c_str()); - if(result != 0) { - utility::handleSystemError(result, "scratch::clearValue"); - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; + std::ostringstream oss; + oss << "xsc_scratch clear " << key; + int result = std::system(oss.str().c_str()); + if (result != 0) { + utility::handleSystemError(result, "scratch::clearValue"); + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; } diff --git a/bsp_q7s/memory/scratchApi.h b/bsp_q7s/memory/scratchApi.h index ee19e084..96264995 100644 --- a/bsp_q7s/memory/scratchApi.h +++ b/bsp_q7s/memory/scratchApi.h @@ -1,17 +1,17 @@ #ifndef BSP_Q7S_MEMORY_SCRATCHAPI_H_ #define BSP_Q7S_MEMORY_SCRATCHAPI_H_ +#include +#include +#include +#include +#include + #include "fsfw/returnvalues/HasReturnvaluesIF.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "linux/utility/utility.h" #include "returnvalues/classIds.h" -#include -#include -#include -#include -#include - /** * @brief API for the scratch buffer */ @@ -48,7 +48,7 @@ ReturnValue_t readString(std::string key, std::string& string); * @param num Number. Template allows to set signed, unsigned and floating point numbers * @return */ -template::value>::type> +template ::value>::type> inline ReturnValue_t writeNumber(std::string key, T num) noexcept; /** @@ -59,90 +59,88 @@ inline ReturnValue_t writeNumber(std::string key, T num) noexcept; * @param num * @return */ -template::value>::type> +template ::value>::type> inline ReturnValue_t readNumber(std::string key, T& num) noexcept; - // Anonymous namespace namespace { static uint8_t counter = 0; ReturnValue_t readToFile(std::string name, std::ifstream& file, std::string& filename) { - using namespace std; - filename = "/tmp/sro" + std::to_string(counter++); - ostringstream oss; - oss << "xsc_scratch read " << name << " > " << filename; + using namespace std; + filename = "/tmp/sro" + std::to_string(counter++); + ostringstream oss; + oss << "xsc_scratch read " << name << " > " << filename; - int result = std::system(oss.str().c_str()); - if(result != 0) { - if(result == 256) { - sif::warning << "scratch::readNumber: Key " << name << " does not exist" << std::endl; - // Could not find value - std::remove(filename.c_str()); - return KEY_NOT_FOUND; - } - else { - utility::handleSystemError(result, "scratch::readNumber"); - std::remove(filename.c_str()); - return HasReturnvaluesIF::RETURN_FAILED; - } + int result = std::system(oss.str().c_str()); + if (result != 0) { + if (WEXITSTATUS(result) == 1) { + sif::warning << "scratch::readNumber: Key " << name << " does not exist" << std::endl; + // Could not find value + std::remove(filename.c_str()); + return KEY_NOT_FOUND; + } else { + utility::handleSystemError(result, "scratch::readNumber"); + std::remove(filename.c_str()); + return HasReturnvaluesIF::RETURN_FAILED; } - file.open(filename); - return HasReturnvaluesIF::RETURN_OK; + } + file.open(filename); + return HasReturnvaluesIF::RETURN_OK; } -} // End of anonymous namespace +} // End of anonymous namespace -template::value>::type> +template ::value>::type> inline ReturnValue_t writeNumber(std::string key, T num) noexcept { - std::ostringstream oss; - oss << "xsc_scratch write " << key << " " << std::to_string(num); - int result = std::system(oss.str().c_str()); - if(result != 0) { - utility::handleSystemError(result, "scratch::writeNumber"); - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; + std::ostringstream oss; + oss << "xsc_scratch write " << key << " " << std::to_string(num); + int result = std::system(oss.str().c_str()); + if (result != 0) { + utility::handleSystemError(result, "scratch::writeNumber"); + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; } -template::value>::type> +template ::value>::type> inline ReturnValue_t readNumber(std::string key, T& num) noexcept { - using namespace std; - ifstream file; - std::string filename; - ReturnValue_t result = readToFile(key, file, filename); - if(result != HasReturnvaluesIF::RETURN_OK) { - std::remove(filename.c_str()); - return result; - } - - string line; - if (not std::getline(file, line)) { - std::remove(filename.c_str()); - return HasReturnvaluesIF::RETURN_FAILED; - } - - size_t pos = line.find("="); - if(pos == string::npos) { - sif::warning << "scratch::readNumber: Output file format invalid, " - "no \"=\" found" << std::endl; - // Could not find value - std::remove(filename.c_str()); - return KEY_NOT_FOUND; - } - std::string valueAsString = line.substr(pos + 1); - try { - num = std::stoi(valueAsString); - } - catch(std::invalid_argument& e) { - sif::warning << "scratch::readNumber: stoi call failed with " << e.what() << std::endl; - } - + using namespace std; + ifstream file; + std::string filename; + ReturnValue_t result = readToFile(key, file, filename); + if (result != HasReturnvaluesIF::RETURN_OK) { std::remove(filename.c_str()); - return HasReturnvaluesIF::RETURN_OK; + return result; + } + + string line; + if (not std::getline(file, line)) { + std::remove(filename.c_str()); + return HasReturnvaluesIF::RETURN_FAILED; + } + + size_t pos = line.find("="); + if (pos == string::npos) { + sif::warning << "scratch::readNumber: Output file format invalid, " + "no \"=\" found" + << std::endl; + // Could not find value + std::remove(filename.c_str()); + return KEY_NOT_FOUND; + } + std::string valueAsString = line.substr(pos + 1); + try { + num = std::stoi(valueAsString); + } catch (std::invalid_argument& e) { + sif::warning << "scratch::readNumber: stoi call failed with " << e.what() << std::endl; + } + + std::remove(filename.c_str()); + return HasReturnvaluesIF::RETURN_OK; } -} +} // namespace scratch #endif /* BSP_Q7S_MEMORY_SCRATCHAPI_H_ */ diff --git a/bsp_q7s/simple/CMakeLists.txt b/bsp_q7s/simple/CMakeLists.txt index 399a1dd3..77cbd076 100644 --- a/bsp_q7s/simple/CMakeLists.txt +++ b/bsp_q7s/simple/CMakeLists.txt @@ -1,3 +1,3 @@ -target_sources(${TARGET_NAME} PRIVATE +target_sources(${SIMPLE_OBSW_NAME} PRIVATE simple.cpp ) diff --git a/bsp_q7s/simple/simple.cpp b/bsp_q7s/simple/simple.cpp index 960aa7db..1362ef23 100644 --- a/bsp_q7s/simple/simple.cpp +++ b/bsp_q7s/simple/simple.cpp @@ -1,4 +1,6 @@ #include "simple.h" + +#include "iostream" #include "q7sConfig.h" #if Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST == 1 @@ -6,16 +8,13 @@ #endif int simple::simple() { - cout << "-- Q7S Simple Application --" << endl; + std::cout << "-- Q7S Simple Application --" << std::endl; #if Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST == 1 - { - FileSystemTest fileSystemTest; - } + { FileSystemTest fileSystemTest; } #endif #if TE0720_GPIO_TEST #endif - return 0; + return 0; } - diff --git a/bsp_q7s/spi/Q7sSpiComIF.cpp b/bsp_q7s/spi/Q7sSpiComIF.cpp index 23dbe551..84552503 100644 --- a/bsp_q7s/spi/Q7sSpiComIF.cpp +++ b/bsp_q7s/spi/Q7sSpiComIF.cpp @@ -1,9 +1,5 @@ #include -Q7sSpiComIF::Q7sSpiComIF(object_id_t objectId, GpioIF* gpioComIF) : - SpiComIF(objectId, gpioComIF) { -} - -Q7sSpiComIF::~Q7sSpiComIF() { -} +Q7sSpiComIF::Q7sSpiComIF(object_id_t objectId, GpioIF* gpioComIF) : SpiComIF(objectId, gpioComIF) {} +Q7sSpiComIF::~Q7sSpiComIF() {} diff --git a/bsp_q7s/spi/Q7sSpiComIF.h b/bsp_q7s/spi/Q7sSpiComIF.h index a10d63dd..def754ab 100644 --- a/bsp_q7s/spi/Q7sSpiComIF.h +++ b/bsp_q7s/spi/Q7sSpiComIF.h @@ -3,7 +3,6 @@ #include - /** * @brief This additional communication interface is required because the SPI busses behind the * devices "/dev/spi2.0" and "dev/spidev3.0" are multiplexed to one SPI interface. @@ -17,17 +16,17 @@ * the SPI interface. The multiplexing is performed via a GPIO connected to a VHDL * module responsible for switching between the to SPI peripherals. */ -class Q7sSpiComIF: public SpiComIF { -public: - /** - * @brief Constructor - * - * @param objectId - * @param gpioComIF - * @param gpioSwitchId The gpio ID of the GPIO connected to the SPI mux module in the PL. - */ - Q7sSpiComIF(object_id_t objectId, GpioIF* gpioComIF, gpioId_t gpioSwitchId); - virtual ~Q7sSpiComIF(); +class Q7sSpiComIF : public SpiComIF { + public: + /** + * @brief Constructor + * + * @param objectId + * @param gpioComIF + * @param gpioSwitchId The gpio ID of the GPIO connected to the SPI mux module in the PL. + */ + Q7sSpiComIF(object_id_t objectId, GpioIF* gpioComIF, gpioId_t gpioSwitchId); + virtual ~Q7sSpiComIF(); }; #endif /* BSP_Q7S_SPI_Q7SSPICOMIF_H_ */ diff --git a/bsp_q7s/xadc/CMakeLists.txt b/bsp_q7s/xadc/CMakeLists.txt new file mode 100644 index 00000000..0f2ea7df --- /dev/null +++ b/bsp_q7s/xadc/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(${OBSW_NAME} PRIVATE + Xadc.cpp +) \ No newline at end of file diff --git a/bsp_q7s/xadc/Xadc.cpp b/bsp_q7s/xadc/Xadc.cpp new file mode 100644 index 00000000..e1f1a505 --- /dev/null +++ b/bsp_q7s/xadc/Xadc.cpp @@ -0,0 +1,144 @@ +#include "Xadc.h" + +#include +#include + +#include + +#include "fsfw/serviceinterface/ServiceInterfaceStream.h" + +Xadc::Xadc() {} + +Xadc::~Xadc() {} + +ReturnValue_t Xadc::getTemperature(float& temperature) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + int raw = 0; + int offset = 0; + float scale = 0; + result = readValFromFile(xadc::file::tempRaw.c_str(), raw); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = readValFromFile(xadc::file::tempOffset.c_str(), offset); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = readValFromFile(xadc::file::tempScale.c_str(), scale); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + temperature = (raw + offset) * scale / 1000; + return result; +} + +ReturnValue_t Xadc::getVccPint(float& vccPint) { + ReturnValue_t result = + readVoltageFromSysfs(xadc::file::vccpintRaw, xadc::file::vccpintScale, vccPint); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Xadc::getVccPaux(float& vccPaux) { + ReturnValue_t result = + readVoltageFromSysfs(xadc::file::vccpauxRaw, xadc::file::vccpauxScale, vccPaux); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Xadc::getVccInt(float& vccInt) { + ReturnValue_t result = + readVoltageFromSysfs(xadc::file::vccintRaw, xadc::file::vccintScale, vccInt); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Xadc::getVccAux(float& vccAux) { + ReturnValue_t result = + readVoltageFromSysfs(xadc::file::vccauxRaw, xadc::file::vccauxScale, vccAux); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Xadc::getVccBram(float& vccBram) { + ReturnValue_t result = + readVoltageFromSysfs(xadc::file::vccbramRaw, xadc::file::vccbramScale, vccBram); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Xadc::getVccOddr(float& vccOddr) { + ReturnValue_t result = + readVoltageFromSysfs(xadc::file::vccoddrRaw, xadc::file::vccoddrScale, vccOddr); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Xadc::getVrefp(float& vrefp) { + ReturnValue_t result = readVoltageFromSysfs(xadc::file::vrefpRaw, xadc::file::vrefpScale, vrefp); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Xadc::getVrefn(float& vrefn) { + ReturnValue_t result = readVoltageFromSysfs(xadc::file::vrefnRaw, xadc::file::vrefnScale, vrefn); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Xadc::readVoltageFromSysfs(std::string rawFile, std::string scaleFile, + float& voltage) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + float raw = 0; + float scale = 0; + result = readValFromFile(rawFile.c_str(), raw); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = readValFromFile(scaleFile.c_str(), scale); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + voltage = calculateVoltage(raw, scale); + return result; +} + +float Xadc::calculateVoltage(int raw, float scale) { return static_cast(raw * scale); } + +template +ReturnValue_t Xadc::readValFromFile(const char* filename, T& val) { + FILE* fp; + fp = fopen(filename, "r"); + if (fp == nullptr) { + sif::warning << "Xadc::readValFromFile: Failed to open file " << filename << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + char valstring[MAX_STR_LENGTH] = ""; + char* returnVal = fgets(valstring, MAX_STR_LENGTH, fp); + if (returnVal == nullptr) { + sif::warning << "Xadc::readValFromFile: Failed to read string from file " << filename + << std::endl; + fclose(fp); + return HasReturnvaluesIF::RETURN_FAILED; + } + std::istringstream valSstream(valstring); + valSstream >> val; + fclose(fp); + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/bsp_q7s/xadc/Xadc.h b/bsp_q7s/xadc/Xadc.h new file mode 100644 index 00000000..92ec2c0c --- /dev/null +++ b/bsp_q7s/xadc/Xadc.h @@ -0,0 +1,108 @@ +#ifndef BSP_Q7S_XADC_XADC_H_ +#define BSP_Q7S_XADC_XADC_H_ + +#include + +#include "fsfw/returnvalues/HasReturnvaluesIF.h" + +namespace xadc { +using namespace std; +static const string iioPath = "/sys/bus/iio/devices/iio:device1"; +namespace file { +static const string tempOffset = iioPath + "/in_temp0_offset"; +static const string tempRaw = iioPath + "/in_temp0_raw"; +static const string tempScale = iioPath + "/in_temp0_scale"; +static const string vccintRaw = iioPath + "/in_voltage0_vccint_raw"; +static const string vccintScale = iioPath + "/in_voltage0_vccint_scale"; +static const string vccauxRaw = iioPath + "/in_voltage1_vccaux_raw"; +static const string vccauxScale = iioPath + "/in_voltage1_vccaux_scale"; +static const string vccbramRaw = iioPath + "/in_voltage2_vccbram_raw"; +static const string vccbramScale = iioPath + "/in_voltage2_vccbram_scale"; +static const string vccpintRaw = iioPath + "/in_voltage3_vccpint_raw"; +static const string vccpintScale = iioPath + "/in_voltage3_vccpint_scale"; +static const string vccpauxRaw = iioPath + "/in_voltage4_vccpaux_raw"; +static const string vccpauxScale = iioPath + "/in_voltage4_vccpaux_scale"; +static const string vccoddrRaw = iioPath + "/in_voltage5_vccoddr_raw"; +static const string vccoddrScale = iioPath + "/in_voltage5_vccoddr_scale"; +static const string vrefpRaw = iioPath + "/in_voltage6_vrefp_raw"; +static const string vrefpScale = iioPath + "/in_voltage6_vrefp_scale"; +static const string vrefnRaw = iioPath + "/in_voltage7_vrefn_raw"; +static const string vrefnScale = iioPath + "/in_voltage7_vrefn_scale"; +} // namespace file +} // namespace xadc + +/** + * @brief Class providing access to the data generated by the analog mixed signal module (XADC). + * + * @details Details about the XADC peripheral of the Zynq-7020 can be found in the UG480 "7-Series + * FPGAs and Zynq-7000 SoC XADC Dual 12-Bit 1 MSPS Analog-to-Digital Converter" user guide + * from Xilinx. + * + * @author J. Meier + */ +class Xadc { + public: + /** + * @brief Constructor + */ + Xadc(); + virtual ~Xadc(); + + /** + * @brief Returns on-chip temperature degree celcius + */ + ReturnValue_t getTemperature(float& temperature); + + /** + * @brief Returns PS internal logic supply voltage in millivolts + */ + ReturnValue_t getVccPint(float& vccPint); + + /** + * @brief Returns PS auxiliary supply voltage in millivolts + */ + ReturnValue_t getVccPaux(float& vccPaux); + + /** + * @brief Returns PL internal supply voltage in millivolts + */ + ReturnValue_t getVccInt(float& vccInt); + + /** + * @brief Returns PL auxiliary supply voltage in millivolts + */ + ReturnValue_t getVccAux(float& vccAux); + + /** + * @brief Returns PL block RAM supply voltage in millivolts + */ + ReturnValue_t getVccBram(float& vccBram); + + /** + * @brief Returns the PS DDR I/O supply voltage + */ + ReturnValue_t getVccOddr(float& vcOddr); + + /** + * @brief Returns XADC reference input voltage relative to GND in millivolts + */ + ReturnValue_t getVrefp(float& vrefp); + + /** + * @brief Returns negative reference input voltage. Should normally be 0 V. + */ + ReturnValue_t getVrefn(float& vrefn); + + private: + // Maximum length of the string representation of a value in a xadc sysfs file + static const uint8_t MAX_STR_LENGTH = 15; + + ReturnValue_t readVoltageFromSysfs(std::string rawFile, std::string scaleFile, float& voltage); + + float calculateVoltage(int raw, float scale); + + template + ReturnValue_t readValFromFile(const char* filename, T& val); +}; + +#endif /* BSP_Q7S_XADC_XADC_H_ */ diff --git a/bsp_te0720_1cfa/CMakeLists.txt b/bsp_te0720_1cfa/CMakeLists.txt new file mode 100644 index 00000000..cb02f937 --- /dev/null +++ b/bsp_te0720_1cfa/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${OBSW_NAME} PUBLIC + InitMission.cpp + main.cpp + ObjectFactory.cpp +) + +add_subdirectory(boardconfig) diff --git a/bsp_te0720_1cfa/InitMission.cpp b/bsp_te0720_1cfa/InitMission.cpp new file mode 100644 index 00000000..6b39cfb6 --- /dev/null +++ b/bsp_te0720_1cfa/InitMission.cpp @@ -0,0 +1,188 @@ +#include "InitMission.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "OBSWConfig.h" +#include "ObjectFactory.h" +#include "objects/systemObjectList.h" +#include "pollingsequence/pollingSequenceFactory.h" + +ServiceInterfaceStream sif::debug("DEBUG"); +ServiceInterfaceStream sif::info("INFO"); +ServiceInterfaceStream sif::warning("WARNING"); +ServiceInterfaceStream sif::error("ERROR"); + +ObjectManagerIF* objectManager = nullptr; + +void initmission::initMission() { + sif::info << "Building global objects.." << std::endl; + /* Instantiate global object manager and also create all objects */ + ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr); + sif::info << "Initializing all objects.." << std::endl; + ObjectManager::instance()->initialize(); + + /* This function creates and starts all tasks */ + initTasks(); +} + +void initmission::initTasks() { + TaskFactory* factory = TaskFactory::instance(); + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if (factory == nullptr) { + /* Should never happen ! */ + return; + } +#if OBSW_PRINT_MISSED_DEADLINES == 1 + void (*missedDeadlineFunc)(void) = TaskFactory::printMissedDeadline; +#else + void (*missedDeadlineFunc)(void) = nullptr; +#endif + + /* TMTC Distribution */ + PeriodicTaskIF* tmtcDistributor = factory->createPeriodicTask( + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = tmtcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + result = tmtcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + result = tmtcDistributor->addComponent(objects::TM_FUNNEL); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + + PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask( + "TMTC_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component TMTC Bridge failed" << std::endl; + } + PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( + "TMTC_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component TMTC Polling failed" << std::endl; + } + + /* PUS Services */ + std::vector pusTasks; + createPusTasks(*factory, missedDeadlineFunc, pusTasks); + + std::vector pstTasks; + FixedTimeslotTaskIF* pst = factory->createFixedTimeslotTask( + "UART_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc); + result = pst::pstUart(pst); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; + } + pstTasks.push_back(pst); + + PeriodicTaskIF* mpsocHelperTask = factory->createPeriodicTask( + "PLOC_MPSOC_HELPER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = mpsocHelperTask->addComponent(objects::PLOC_MPSOC_HELPER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PLOC_MPSOC_HELPER", objects::PLOC_MPSOC_HELPER); + } + pstTasks.push_back(mpsocHelperTask); + + auto taskStarter = [](std::vector& taskVector, std::string name) { + for (const auto& task : taskVector) { + if (task != nullptr) { + task->startTask(); + } else { + sif::error << "Task in vector " << name << " is invalid!" << std::endl; + } + } + }; + + sif::info << "Starting tasks.." << std::endl; + tmtcDistributor->startTask(); + tmtcBridgeTask->startTask(); + tmtcPollingTask->startTask(); + + taskStarter(pstTasks, "PST Tasks"); + taskStarter(pusTasks, "PUS Tasks"); + + sif::info << "Tasks started.." << std::endl; +} + +void initmission::createPusTasks(TaskFactory& factory, + TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + PeriodicTaskIF* pusVerification = factory.createPeriodicTask( + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Object add component failed" << std::endl; + } + taskVec.push_back(pusVerification); + + PeriodicTaskIF* pusEvents = factory.createPeriodicTask( + "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); + } + result = pusEvents->addComponent(objects::EVENT_MANAGER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER); + } + taskVec.push_back(pusEvents); + + PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask( + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); + } + result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); + } + taskVec.push_back(pusHighPrio); + + PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask( + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS3", objects::PUS_SERVICE_3_HOUSEKEEPING); + } + taskVec.push_back(pusMedPrio); + + PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); + } + result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("INT_ERR_RPRT", objects::INTERNAL_ERROR_REPORTER); + } + taskVec.push_back(pusLowPrio); +} diff --git a/bsp_te0720_1cfa/InitMission.h b/bsp_te0720_1cfa/InitMission.h new file mode 100644 index 00000000..c3ba58ec --- /dev/null +++ b/bsp_te0720_1cfa/InitMission.h @@ -0,0 +1,21 @@ +#ifndef BSP_LINUX_INITMISSION_H_ +#define BSP_LINUX_INITMISSION_H_ + +#include + +#include "fsfw/tasks/Typedef.h" + +class PeriodicTaskIF; +class TaskFactory; + +namespace initmission { +void initMission(); +void initTasks(); + +void createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec); +void createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, + std::vector& taskVec); +}; // namespace initmission + +#endif /* BSP_LINUX_INITMISSION_H_ */ diff --git a/bsp_te0720_1cfa/ObjectFactory.cpp b/bsp_te0720_1cfa/ObjectFactory.cpp new file mode 100644 index 00000000..757cf31c --- /dev/null +++ b/bsp_te0720_1cfa/ObjectFactory.cpp @@ -0,0 +1,152 @@ +#include "ObjectFactory.h" + +#include +#include "fsfw_hal/linux/uart/UartComIF.h" +#include "fsfw_hal/linux/i2c/I2cComIF.h" +#include "fsfw_hal/linux/uart/UartCookie.h" + +#include "OBSWConfig.h" +#include "busConf.h" +#include "devConf.h" +#include "fsfw/datapoollocal/LocalDataPoolManager.h" +#include "fsfw/tmtcpacket/pus/tm.h" +#include "fsfw/tmtcservices/CommandingServiceBase.h" +#include "fsfw/tmtcservices/PusServiceBase.h" +#include "fsfw_hal/linux/i2c/I2cCookie.h" +#include "linux/devices/ploc/PlocMPSoCHandler.h" +#include "linux/devices/ploc/PlocMPSoCHelper.h" +#include "mission/devices/Tmp1075Handler.h" +#include "mission/core/GenericFactory.h" +#include "mission/utility/TmFunnel.h" +#include "test/gpio/DummyGpioIF.h" +#include "objects/systemObjectList.h" +#include "devices/addresses.h" +#include "devices/gpioIds.h" +#include "tmtc/apid.h" +#include "tmtc/pusIds.h" + +void Factory::setStaticFrameworkObjectIds() { + PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; + PusServiceBase::packetDestination = objects::TM_FUNNEL; + + CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; + CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; + + TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; + TmFunnel::storageDestination = objects::NO_OBJECT; + + VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION; + TmPacketBase::timeStamperId = objects::TIME_STAMPER; +} + +void ObjectFactory::produce(void* args) { + Factory::setStaticFrameworkObjectIds(); + ObjectFactory::produceGenericObjects(); + +#if OBSW_ADD_PLOC_MPSOC == 1 + UartCookie* mpsocUartCookie = + new UartCookie(objects::PLOC_MPSOC_HANDLER, te0720_1cfa::MPSOC_UART, UartModes::NON_CANONICAL, + uart::PLOC_MPSOC_BAUD, mpsoc::MAX_REPLY_SIZE); + mpsocUartCookie->setNoFixedSizeReply(); + PlocMPSoCHelper* plocMpsocHelper = new PlocMPSoCHelper(objects::PLOC_MPSOC_HELPER); + new UartComIF(objects::UART_COM_IF); + auto dummyGpioIF = new DummyGpioIF(); + PlocMPSoCHandler* plocMPSoCHandler = + new PlocMPSoCHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, mpsocUartCookie, + plocMpsocHelper, Gpio(gpioIds::ENABLE_MPSOC_UART, dummyGpioIF)); + plocMPSoCHandler->setStartUpImmediately(); +#endif /* OBSW_ADD_PLOC_MPSOC == 1 */ + +#if OBSW_TEST_LIBGPIOD == 1 +#if OBSW_TEST_GPIO_OPEN_BYLABEL == 1 + /* Configure MIO0 as input */ + GpiodRegular* testGpio = new GpiodRegular("MIO0", Direction::OUT, 0, "/amba_pl/gpio@41200000", 0); +#elif OBSW_TEST_GPIO_OPEN_BY_LINE_NAME + GpiodRegularByLineName* testGpio = + new GpiodRegularByLineName("test-name", "gpio-test", Direction::OUT, 0); +#else + /* Configure MIO0 as input */ + GpiodRegular* testGpio = new GpiodRegular("gpiochip0", 0, "MIO0", gpio::IN, 0); +#endif /* OBSW_TEST_GPIO_LABEL == 1 */ + GpioCookie* gpioCookie = new GpioCookie; + gpioCookie->addGpio(gpioIds::TEST_ID_0, testGpio); + new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); +#endif + +#if OBSW_TEST_SUS == 1 + GpioCookie* gpioCookieSus = new GpioCookie; + GpiodRegular* chipSelectSus = new GpiodRegular( + std::string("gpiochip1"), 9, std::string("Chip Select Sus Sensor"), Direction::OUT, 1); + gpioCookieSus->addGpio(gpioIds::CS_SUS_0, chipSelectSus); + gpioComIF->addGpios(gpioCookieSus); + + SpiCookie* spiCookieSus = + new SpiCookie(addresses::SUS_0, std::string("/dev/spidev1.0"), SUS::MAX_CMD_SIZE, + spi::DEFAULT_MAX_1227_MODE, spi::DEFAULT_MAX_1227_SPEED); + + new SusHandler(objects::SUS_0, objects::SPI_COM_IF, spiCookieSus, gpioComIF, gpioIds::CS_SUS_0); +#endif + +#if OBSW_TEST_CCSDS_BRIDGE == 1 + GpioCookie* gpioCookieCcsdsIp = new GpioCookie; + GpiodRegular* papbBusyN = + new GpiodRegular(std::string("gpiochip0"), 0, std::string("PAPBBusy_VC0")); + gpioCookieCcsdsIp->addGpio(gpioIds::PAPB_BUSY_N, papbBusyN); + GpiodRegular* papbEmpty = + new GpiodRegular(std::string("gpiochip0"), 1, std::string("PAPBEmpty_VC0")); + gpioCookieCcsdsIp->addGpio(gpioIds::PAPB_EMPTY, papbEmpty); + gpioComIF->addGpios(gpioCookieCcsdsIp); + + new CCSDSIPCoreBridge(objects::CCSDS_IP_CORE_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR, + objects::TM_STORE, objects::TC_STORE, gpioComIF, std::string("/dev/uio0"), + gpioIds::PAPB_BUSY_N, gpioIds::PAPB_EMPTY); +#endif + +#if OBSW_TEST_RAD_SENSOR == 1 + GpioCookie* gpioCookieRadSensor = new GpioCookie; + GpiodRegular* chipSelectRadSensor = new GpiodRegular( + std::string("gpiochip1"), 0, std::string("Chip select radiation sensor"), Direction::OUT, 1); + gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, chipSelectRadSensor); + gpioComIF->addGpios(gpioCookieRadSensor); + + SpiCookie* spiCookieRadSensor = + new SpiCookie(addresses::RAD_SENSOR, gpioIds::CS_RAD_SENSOR, std::string("/dev/spidev1.0"), + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::DEFAULT_MAX_1227_SPEED); + + RadiationSensorHandler* radSensor = + new RadiationSensorHandler(objects::RAD_SENSOR, objects::SPI_COM_IF, spiCookieRadSensor); + radSensor->setStartUpImmediately(); +#endif + +#if OBSW_TEST_TE7020_HEATER == 1 + /* Configuration for MIO0 on TE0720-03-1CFA */ + GpiodRegular* heaterGpio = + new GpiodRegular(std::string("gpiochip0"), 0, std::string("MIO0"), gpio::IN, 0); + GpioCookie* gpioCookie = new GpioCookie; + gpioCookie->addGpio(gpioIds::HEATER_0, heaterGpio); + new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie, objects::PCDU_HANDLER, + pcduSwitches::TCS_BOARD_8V_HEATER_IN); +#endif + +#if OBSW_ADD_PLOC_SUPERVISOR == 1 + /* Configuration for MIO0 on TE0720-03-1CFA */ + UartCookie* plocSupervisorCookie = + new UartCookie(objects::PLOC_SUPERVISOR_HANDLER, std::string("/dev/ttyPS1"), + UartModes::NON_CANONICAL, 115200, PLOC_SPV::MAX_PACKET_SIZE * 20); + plocSupervisorCookie->setNoFixedSizeReply(); + PlocSupervisorHandler* plocSupervisor = new PlocSupervisorHandler( + objects::PLOC_SUPERVISOR_HANDLER, objects::UART_COM_IF, plocSupervisorCookie); + plocSupervisor->setStartUpImmediately(); +#endif + +new I2cComIF(objects::I2C_COM_IF); + +I2cCookie* i2cCookieTmp1075tcs1 = + new I2cCookie(addresses::TMP1075_TCS_1, TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0")); +I2cCookie* i2cCookieTmp1075tcs2 = + new I2cCookie(addresses::TMP1075_TCS_2, TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0")); + +/* Temperature sensors */ +new Tmp1075Handler(objects::TMP1075_HANDLER_1, objects::I2C_COM_IF, i2cCookieTmp1075tcs1); +new Tmp1075Handler(objects::TMP1075_HANDLER_2, objects::I2C_COM_IF, i2cCookieTmp1075tcs2); +} diff --git a/bsp_te0720_1cfa/ObjectFactory.h b/bsp_te0720_1cfa/ObjectFactory.h new file mode 100644 index 00000000..b24dd321 --- /dev/null +++ b/bsp_te0720_1cfa/ObjectFactory.h @@ -0,0 +1,8 @@ +#ifndef BSP_LINUX_OBJECTFACTORY_H_ +#define BSP_LINUX_OBJECTFACTORY_H_ + +namespace ObjectFactory { +void produce(void* args); +}; // namespace ObjectFactory + +#endif /* BSP_LINUX_OBJECTFACTORY_H_ */ diff --git a/bsp_te0720_1cfa/boardconfig/CMakeLists.txt b/bsp_te0720_1cfa/boardconfig/CMakeLists.txt new file mode 100644 index 00000000..f9136e3e --- /dev/null +++ b/bsp_te0720_1cfa/boardconfig/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${OBSW_NAME} PRIVATE + print.c +) + +target_include_directories(${OBSW_NAME} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/bsp_te0720_1cfa/boardconfig/busConf.h b/bsp_te0720_1cfa/boardconfig/busConf.h new file mode 100644 index 00000000..893014c1 --- /dev/null +++ b/bsp_te0720_1cfa/boardconfig/busConf.h @@ -0,0 +1,11 @@ +#ifndef BSP_EGSE_BOARDCONFIG_BUSCONF_H_ +#define BSP_EGSE_BOARDCONFIG_BUSCONF_H_ + +namespace te0720_1cfa { +static constexpr char MPSOC_UART[] = "/dev/ttyPS1"; +namespace baudrate { + +} +} + +#endif /* BSP_EGSE_BOARDCONFIG_BUSCONF_H_ */ diff --git a/bsp_te0720_1cfa/boardconfig/etl_profile.h b/bsp_te0720_1cfa/boardconfig/etl_profile.h new file mode 100644 index 00000000..54aca344 --- /dev/null +++ b/bsp_te0720_1cfa/boardconfig/etl_profile.h @@ -0,0 +1,38 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2019 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ +#ifndef __ETL_PROFILE_H__ +#define __ETL_PROFILE_H__ + +#define ETL_CHECK_PUSH_POP + +#define ETL_CPP11_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 + +#endif diff --git a/bsp_te0720_1cfa/boardconfig/gcov.h b/bsp_te0720_1cfa/boardconfig/gcov.h new file mode 100644 index 00000000..80acdd86 --- /dev/null +++ b/bsp_te0720_1cfa/boardconfig/gcov.h @@ -0,0 +1,15 @@ +#ifndef LINUX_GCOV_H_ +#define LINUX_GCOV_H_ +#include + +#ifdef GCOV +extern "C" void __gcov_flush(); +#else +void __gcov_flush() { + sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if " + "coverage information is desired.\n" + << std::flush; +} +#endif + +#endif /* LINUX_GCOV_H_ */ diff --git a/bsp_te0720_1cfa/boardconfig/print.c b/bsp_te0720_1cfa/boardconfig/print.c new file mode 100644 index 00000000..1739e90b --- /dev/null +++ b/bsp_te0720_1cfa/boardconfig/print.c @@ -0,0 +1,10 @@ +#include +#include + +void printChar(const char* character, bool errStream) { + if (errStream) { + putc(*character, stderr); + return; + } + putc(*character, stdout); +} diff --git a/bsp_te0720_1cfa/boardconfig/print.h b/bsp_te0720_1cfa/boardconfig/print.h new file mode 100644 index 00000000..8e7e2e5d --- /dev/null +++ b/bsp_te0720_1cfa/boardconfig/print.h @@ -0,0 +1,8 @@ +#ifndef HOSTED_BOARDCONFIG_PRINT_H_ +#define HOSTED_BOARDCONFIG_PRINT_H_ + +#include + +void printChar(const char* character, bool errStream); + +#endif /* HOSTED_BOARDCONFIG_PRINT_H_ */ diff --git a/bsp_te0720_1cfa/main.cpp b/bsp_te0720_1cfa/main.cpp new file mode 100644 index 00000000..cb7d987e --- /dev/null +++ b/bsp_te0720_1cfa/main.cpp @@ -0,0 +1,29 @@ +#include + +#include "InitMission.h" +#include "OBSWConfig.h" +#include "OBSWVersion.h" +#include "fsfw/version.h" +#include "fsfw/tasks/TaskFactory.h" + +/** + * @brief This is the main program entry point for the obsw running on the trenz electronic + * te0720-1cfa. + * @return + */ +int main(void) { + using namespace fsfw; + std::cout << "-- EIVE OBSW --" << std::endl; + std::cout << "-- Compiled for Trenz TE0720-1CFA" + << " --" << std::endl; + std::cout << "-- OBSW v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_REVISION << ", FSFW v" + << FSFW_VERSION << "--" << std::endl; + std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; + + initmission::initMission(); + + for (;;) { + /* Suspend main thread by sleeping it. */ + TaskFactory::delayTask(5000); + } +} diff --git a/cmake/HardwareOsPostConfig.cmake b/cmake/HardwareOsPostConfig.cmake index 2492b9bb..e7fb257a 100644 --- a/cmake/HardwareOsPostConfig.cmake +++ b/cmake/HardwareOsPostConfig.cmake @@ -3,7 +3,7 @@ function(post_source_hw_os_config) if(LINK_LWIP) message(STATUS "Linking against ${LIB_LWIP_NAME} lwIP library") if(LIB_LWIP_NAME) - target_link_libraries(${TARGET_NAME} PUBLIC + target_link_libraries(${OBSW_NAME} PUBLIC ${LIB_LWIP_NAME} ) else() @@ -12,7 +12,7 @@ if(LINK_LWIP) endif() if(LINKER_SCRIPT) - target_link_options(${TARGET_NAME} PRIVATE + add_link_options( -T${LINKER_SCRIPT} ) endif() @@ -35,20 +35,20 @@ if(CMAKE_VERBOSE) endif() # Generator expression. Can be used to set different C, CXX and ASM flags. -target_compile_options(${TARGET_NAME} PRIVATE +add_compile_options( $<$:${C_DEFS} ${C_FLAGS}> $<$:${CXX_DEFS} ${CXX_FLAGS}> $<$:${ASM_FLAGS}> ) -set(STRIPPED_TARGET_NAME ${TARGET_NAME}-stripped) +set(STRIPPED_OBSW_NAME ${OBSW_BIN_NAME}-stripped) add_custom_command( - TARGET ${TARGET_NAME} + TARGET ${OBSW_NAME} POST_BUILD - COMMAND ${CMAKE_STRIP} --strip-all ${TARGET_NAME} -o ${STRIPPED_TARGET_NAME} - BYPRODUCTS ${STRIPPED_TARGET_NAME} - COMMENT "Generating stripped executable ${STRIPPED_TARGET_NAME}.." + COMMAND ${CMAKE_STRIP} --strip-all ${OBSW_BIN_NAME} -o ${STRIPPED_OBSW_NAME} + BYPRODUCTS ${STRIPPED_OBSW_NAME} + COMMENT "Generating stripped executable ${STRIPPED_OBSW_NAME}.." ) endfunction() \ No newline at end of file diff --git a/cmake/HardwareOsPreConfig.cmake b/cmake/HardwareOsPreConfig.cmake index 3ff67565..7b90eb54 100644 --- a/cmake/HardwareOsPreConfig.cmake +++ b/cmake/HardwareOsPreConfig.cmake @@ -47,7 +47,7 @@ if(CMAKE_CROSSCOMPILING) set_property(CACHE TGT_BSP PROPERTY STRINGS - "arm/q7s" "arm/raspberrypi" + "arm/q7s" "arm/raspberrypi" "arm/egse" ) endif() @@ -57,6 +57,10 @@ if(TGT_BSP) set(BSP_PATH "bsp_linux_board") elseif(TGT_BSP MATCHES "arm/q7s") set(BSP_PATH "bsp_q7s") + elseif(TGT_BSP MATCHES "arm/egse") + set(BSP_PATH "bsp_egse") + elseif(TGT_BSP MATCHES "arm/te0720-1cfa") + set(BSP_PATH "bsp_te0720_1cfa") else() message(WARNING "CMake not configured for this target!") message(FATAL_ERROR "Target: ${TGT_BSP}!") diff --git a/cmake/PreProjectConfig.cmake b/cmake/PreProjectConfig.cmake index 9f1790bb..41dd7de4 100644 --- a/cmake/PreProjectConfig.cmake +++ b/cmake/PreProjectConfig.cmake @@ -9,14 +9,15 @@ if(DEFINED TGT_BSP) endif() endif() + # Disable compiler checks for cross-compiling. if(FSFW_OSAL MATCHES linux AND TGT_BSP) - if(TGT_BSP MATCHES "arm/q7s") + if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "arm/te0720-1cfa") set(CMAKE_TOOLCHAIN_FILE - "${CMAKE_SCRIPT_PATH}/Q7SCrossCompileConfig.cmake" + "${CMAKE_SCRIPT_PATH}/Zynq7020CrossCompileConfig.cmake" PARENT_SCOPE ) - elseif(TGT_BSP MATCHES "arm/raspberrypi") + elseif(TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/egse") if(NOT DEFINED ENV{LINUX_ROOTFS}) if(NOT DEFINED LINUX_ROOTFS) message(WARNING "No LINUX_ROOTFS environmental or CMake variable set!") diff --git a/cmake/Q7SCrossCompileConfig.cmake b/cmake/Zynq7020CrossCompileConfig.cmake similarity index 81% rename from cmake/Q7SCrossCompileConfig.cmake rename to cmake/Zynq7020CrossCompileConfig.cmake index d4d05f4e..be6702a1 100644 --- a/cmake/Q7SCrossCompileConfig.cmake +++ b/cmake/Zynq7020CrossCompileConfig.cmake @@ -1,16 +1,16 @@ -if(DEFINED ENV{Q7S_SYSROOT}) - set(ENV{Q7S_ROOTFS} $ENV{Q7S_SYSROOT}) +if(DEFINED ENV{ZYNQ_7020_SYSROOT}) + set(ENV{ZYNQ_7020_ROOTFS} $ENV{ZYNQ_7020_SYSROOT}) endif() # CROSS_COMPILE also needs to be set accordingly or passed to the CMake command -if(NOT DEFINED ENV{Q7S_ROOTFS}) +if(NOT DEFINED ENV{ZYNQ_7020_ROOTFS}) # Sysroot has not been cached yet and was not set in environment either if(NOT DEFINED SYSROOT_PATH) message(FATAL_ERROR - "Define the Q7S_ROOTFS variable to point to the Q7S rootfs." + "Define the ZYNQ_7020_ROOTFS variable to point to the Zynq-7020 rootfs." ) endif() else() - set(SYSROOT_PATH "$ENV{Q7S_ROOTFS}" CACHE PATH "Q7S root filesystem path") + set(SYSROOT_PATH "$ENV{ZYNQ_7020_ROOTFS}" CACHE PATH "Zynq-7020 root filesystem path") endif() if(NOT DEFINED ENV{CROSS_COMPILE}) @@ -81,13 +81,27 @@ set(CMAKE_PREFIX_PATH # "${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}" ) +set(C_FLAGS + -mcpu=cortex-a9 + -mfpu=neon-vfpv3 + -mfloat-abi=hard + ${COMMON_FLAGS} + -lgpiod +) + +if (TGT_BSP MATCHES "arm/q7s") + set(C_FLAGS ${C_FLAGS} -lxiphos) +endif() + +string (REPLACE ";" " " C_FLAGS "${C_FLAGS}") + set(CMAKE_C_FLAGS - "-mcpu=cortex-a9 -mfpu=neon-vfpv3 -mfloat-abi=hard ${COMMON_FLAGS} -lgpiod" - CACHE STRING "C flags for Q7S" + ${C_FLAGS} + CACHE STRING "C flags for Zynq-7020" ) set(CMAKE_CXX_FLAGS - "${CMAKE_C_FLAGS}" - CACHE STRING "CPP flags for Q7S" + "${CMAKE_C_FLAGS}" + CACHE STRING "CPP flags for Zynq-7020" ) # search for programs in the build host directories diff --git a/cmake/scripts/Q7S/q7s-env.sh b/cmake/scripts/Q7S/q7s-env.sh new file mode 100755 index 00000000..df9dbadc --- /dev/null +++ b/cmake/scripts/Q7S/q7s-env.sh @@ -0,0 +1,7 @@ +#!/bin/bash -i +export PATH=$PATH:"$HOME/EIVE/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin" +export CROSS_COMPILE="arm-linux-gnueabihf" + +export ZYNQ_7020_SYSROOT="$HOME/Xilinx/cortexa9hf-neon-xiphos-linux-gnueabi" +export CONSOLE_PREFIX="[Q7S ENV]" +/bin/bash diff --git a/cmake/scripts/Q7S/simple/make-simple-debug-cfg.sh b/cmake/scripts/Q7S/simple/make-simple-debug-cfg.sh deleted file mode 100755 index 93f4a087..00000000 --- a/cmake/scripts/Q7S/simple/make-simple-debug-cfg.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -counter=0 -cfg_script_name="cmake-build-cfg.py" -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f ${cfg_script_name} ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "${cfg_script_name} not found in upper directories!" - exit 1 -fi - -os_fsfw="linux" -tgt_bsp="arm/q7s" -build_dir="build-Simple-Q7S" -build_generator="" -definitions="BUILD_Q7S_SIMPLE_MODE=On" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" - python="py" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" - python="python3" -fi - -echo "Running command (without the leading +):" -set -x # Print command -${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ - -l "${build_dir}" -d "${definitions}" -# set +x diff --git a/cmake/scripts/Q7S/unix_path_helper.sh b/cmake/scripts/Q7S/unix_path_helper.sh deleted file mode 100644 index 296bfdd8..00000000 --- a/cmake/scripts/Q7S/unix_path_helper.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -export PATH=$PATH:"/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin" -export CROSS_COMPILE="arm-linux-gnueabihf" - -export Q7S_SYSROOT="$HOME/Xilinx/cortexa9hf-neon-xiphos-linux-gnueabi" - diff --git a/cmake/scripts/Q7S/watchdog/make-debug-cfg.sh b/cmake/scripts/Q7S/watchdog/make-debug-cfg.sh deleted file mode 100755 index 0f829fea..00000000 --- a/cmake/scripts/Q7S/watchdog/make-debug-cfg.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -counter=0 -cfg_script_name="cmake-build-cfg.py" -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f ${cfg_script_name} ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "${cfg_script_name} not found in upper directories!" - exit 1 -fi - -os_fsfw="linux" -tgt_bsp="arm/q7s" -build_dir="build-Debug-Watchdog" -build_generator="" -definitions="EIVE_BUILD_WATCHDOG=ON" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" - python="py" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" - python="python3" -fi - -echo "Running command (without the leading +):" -set -x # Print command -${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ - -d "${definitions}" -l"${build_dir}" -# set +x - diff --git a/cmake/scripts/Q7S/watchdog/make-release-cfg.sh b/cmake/scripts/Q7S/watchdog/make-release-cfg.sh deleted file mode 100755 index c8df73d5..00000000 --- a/cmake/scripts/Q7S/watchdog/make-release-cfg.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -counter=0 -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 -fi - -os_fsfw="linux" -tgt_bsp="arm/q7s" -build_dir="build-Release-Watchdog" -build_generator="" -definitions="EIVE_BUILD_WATCHDOG=ON" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" - python="py" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" - python="python3" -fi - -echo "Running command (without the leading +):" -set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ - -d "${definitions} -l"${build_dir}" -# set +x - diff --git a/cmake/scripts/Q7S/watchdog/ninja-release-cfg.sh b/cmake/scripts/Q7S/watchdog/ninja-release-cfg.sh deleted file mode 100755 index d8f5e18e..00000000 --- a/cmake/scripts/Q7S/watchdog/ninja-release-cfg.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh -counter=0 -cfg_script_name="cmake-build-cfg.py" -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f ${cfg_script_name} ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "${cfg_script_name} not found in upper directories!" - exit 1 -fi - -os_fsfw="linux" -tgt_bsp="arm/q7s" -build_dir="build-Release-Watchdog" -build_generator="Ninja" -definitions="EIVE_BUILD_WATCHDOG=ON" -if [ "${OS}" = "Windows_NT" ]; then - python="py" -# Could be other OS but this works for now. -else - python="python3" -fi - -echo "Running command (without the leading +):" -set -x # Print command -${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ - -d "${definitions}" -l"${build_dir}" -# set +x - diff --git a/cmake/scripts/Q7S/win-q7s-env.sh b/cmake/scripts/Q7S/win-q7s-env.sh new file mode 100644 index 00000000..703949e3 --- /dev/null +++ b/cmake/scripts/Q7S/win-q7s-env.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# Run with: source win-q7s-env.sh [OPTIONS] +function help () { + echo "source win-q7s-env.sh [options] -t|--toolchain= -s|--sysroot=" +} + +TOOLCHAIN_PATH="/c/Xilinx/Vitis/2019.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin" +SYSROOT="/c/Users/${USER}/eive-software/cortexa9hf-neon-xiphos-linux-gnueabi" + +for i in "$@"; do + case $i in + -t=*|--toolchain=*) + TOOLCHAIN_PATH="${i#*=}" + shift + ;; + -s=*|--sysroot=*) + SYSROOT="${i#*=}" + shift + ;; + -h|--help) + help + shift + ;; + -*|--*) + echo "Unknown option $i" + help + return + ;; + *) + ;; + esac +done + +if [ -d "$TOOLCHAIN_PATH" ]; then + export PATH=$PATH:"/c/Xilinx/Vitis/2019.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin" + export CROSS_COMPILE="arm-linux-gnueabihf" + echo "Set toolchain path to /c/Xilinx/Vitis/2019.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin" +else + echo "Toolchain path $TOOLCHAIN_PATH does not exist" + return +fi + +if [ -d "$SYSROOT" ]; then + export ZYNQ_7020_SYSROOT=$SYSROOT + echo "Set sysroot path to $SYSROOT" +else + echo "Sysroot path $SYSROOT does not exist" + return +fi \ No newline at end of file diff --git a/cmake/scripts/Q7S/win_path_helper_xilinx_tools.sh b/cmake/scripts/Q7S/win_path_helper_xilinx_tools.sh deleted file mode 100644 index a8352331..00000000 --- a/cmake/scripts/Q7S/win_path_helper_xilinx_tools.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -export PATH=$PATH:"/c/Xilinx/SDK/2018.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin" -export CROSS_COMPILE="arm-linux-gnueabihf" - -export Q7S_SYSROOT="/c/Users/${USER}/Documents/EIVE/cortexa9hf-neon-xiphos-linux-gnueabi" diff --git a/cmake/scripts/cmake-build-cfg.py b/cmake/scripts/cmake-build-cfg.py index 5d1b1048..4c5ee536 100755 --- a/cmake/scripts/cmake-build-cfg.py +++ b/cmake/scripts/cmake-build-cfg.py @@ -12,6 +12,7 @@ import os import sys import argparse import shutil +import stat def main(): @@ -102,7 +103,7 @@ def main(): build_path = source_location + os.path.sep + build_folder remove_old_dir = False if remove_old_dir: - shutil.rmtree(build_path) + rm_build_dir(build_path) os.chdir(source_location) os.mkdir(build_folder) print(f"Navigating into build directory: {build_path}") @@ -117,6 +118,14 @@ def main(): print(f"\" {cmake_command} \"") os.system(cmake_command) print("-- CMake configuration done. --") + + +def rm_build_dir(path: str): + # On windows the permissions of the build directory may have been set to read-only. If this + # is the case the permissions are changed before trying to delete the directory. + if not os.access(path, os.W_OK): + os.chmod(path, stat.S_IWUSR) + shutil.rmtree(path) def determine_source_location() -> str: diff --git a/cmake/scripts/egse/egse_path_helper_win.sh b/cmake/scripts/egse/egse_path_helper_win.sh new file mode 100644 index 00000000..4bda17b0 --- /dev/null +++ b/cmake/scripts/egse/egse_path_helper_win.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# Script to set path to raspberry pi toolchain +# Run script with: source egse_path_helper_win.sh +TOOLCHAIN_PATH="/c/SysGCC/raspberry/bin" +if [ $# -eq 1 ];then + export PATH=$PATH:"$1" +else + export PATH=$PATH:$TOOLCHAIN_PATH +fi + +echo "Path of toolchain set to $TOOLCHAIN_PATH" +export CROSS_COMPILE="arm-linux-gnueabihf" +export RASPBERRY_VERSION="4" \ No newline at end of file diff --git a/cmake/scripts/Q7S/simple/ninja-simple-debug-cfg.sh b/cmake/scripts/egse/make-debug-cfg.sh old mode 100755 new mode 100644 similarity index 80% rename from cmake/scripts/Q7S/simple/ninja-simple-debug-cfg.sh rename to cmake/scripts/egse/make-debug-cfg.sh index c1805eff..9a611373 --- a/cmake/scripts/Q7S/simple/ninja-simple-debug-cfg.sh +++ b/cmake/scripts/egse/make-debug-cfg.sh @@ -15,11 +15,11 @@ if [ "${counter}" -ge 5 ];then exit 1 fi + os_fsfw="linux" -tgt_bsp="arm/q7s" -build_dir="build-Simple-Q7S" -build_generator="Ninja" -definitions="BUILD_Q7S_SIMPLE_MODE=On" +tgt_bsp="arm/egse" +build_generator="make" +build_dir="build-Debug-egse" if [ "${OS}" = "Windows_NT" ]; then python="py" # Could be other OS but this works for now. @@ -30,6 +30,5 @@ fi echo "Running command (without the leading +):" set -x # Print command ${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ - -l "${build_dir}" -d "${definitions}" + -l"${build_dir}" # set +x - diff --git a/cmake/scripts/Q7S/watchdog/ninja-debug-cfg.sh b/cmake/scripts/te0720-1cfa/make-debug-cfg.sh old mode 100755 new mode 100644 similarity index 80% rename from cmake/scripts/Q7S/watchdog/ninja-debug-cfg.sh rename to cmake/scripts/te0720-1cfa/make-debug-cfg.sh index ed23bb6a..46008c41 --- a/cmake/scripts/Q7S/watchdog/ninja-debug-cfg.sh +++ b/cmake/scripts/te0720-1cfa/make-debug-cfg.sh @@ -15,11 +15,11 @@ if [ "${counter}" -ge 5 ];then exit 1 fi + os_fsfw="linux" -tgt_bsp="arm/q7s" -build_dir="build-Debug-Watchdog" -build_generator="Ninja" -definitions="EIVE_BUILD_WATCHDOG=ON" +tgt_bsp="arm/te0720-1cfa" +build_generator="make" +build_dir="build-Debug-te0720-1cfa" if [ "${OS}" = "Windows_NT" ]; then python="py" # Could be other OS but this works for now. @@ -30,6 +30,5 @@ fi echo "Running command (without the leading +):" set -x # Print command ${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ - -d "${definitions}" -l "${build_dir}" + -l"${build_dir}" # set +x - diff --git a/cmake/scripts/te0720-1cfa/win-env-te0720-1cfa.sh b/cmake/scripts/te0720-1cfa/win-env-te0720-1cfa.sh new file mode 100644 index 00000000..e77de4c8 --- /dev/null +++ b/cmake/scripts/te0720-1cfa/win-env-te0720-1cfa.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# Run with: source q7s-env-win-sh [OPTIONS] +function help () { + echo "source q7s-env-win-sh [options] -t|--toolchain= -s|--sysroot=" +} + +TOOLCHAIN_PATH="/c/Xilinx/Vitis/2019.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin" +SYSROOT="/c/Users/${USER}/eive-software/sysroots-petalinux-2019-2/cortexa9t2hf-neon-xilinx-linux-gnueabi" + +for i in "$@"; do + case $i in + -t=*|--toolchain=*) + TOOLCHAIN_PATH="${i#*=}" + shift + ;; + -s=*|--sysroot=*) + SYSROOT="${i#*=}" + shift + ;; + -h|--help) + help + shift + ;; + -*|--*) + echo "Unknown option $i" + help + return + ;; + *) + ;; + esac +done + +if [ -d "$TOOLCHAIN_PATH" ]; then + export PATH=$PATH:"/c/Xilinx/Vitis/2019.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin" + export CROSS_COMPILE="arm-linux-gnueabihf" + echo "Set toolchain path to /c/Xilinx/Vitis/2019.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin" +else + echo "Toolchain path $TOOLCHAIN_PATH does not exist" + return +fi + +if [ -d "$SYSROOT" ]; then + export ZYNQ_7020_SYSROOT=$SYSROOT + echo "Set sysroot path to $SYSROOT" +else + echo "Sysroot path $SYSROOT does not exist" + return +fi \ No newline at end of file diff --git a/common/config/CMakeLists.txt b/common/config/CMakeLists.txt index 5c4b4942..00848561 100644 --- a/common/config/CMakeLists.txt +++ b/common/config/CMakeLists.txt @@ -1,7 +1,7 @@ -target_include_directories(${TARGET_NAME} PRIVATE +target_include_directories(${OBSW_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) -target_sources(${TARGET_NAME} PRIVATE +target_sources(${OBSW_NAME} PRIVATE commonConfig.cpp ) \ No newline at end of file diff --git a/common/config/OBSWVersion.h b/common/config/OBSWVersion.h index 39cb356a..71fd3355 100644 --- a/common/config/OBSWVersion.h +++ b/common/config/OBSWVersion.h @@ -4,7 +4,7 @@ const char* const SW_NAME = "eive"; #define SW_VERSION 1 -#define SW_SUBVERSION 8 -#define SW_REVISION 0 +#define SW_SUBVERSION 9 +#define SW_REVISION 1 #endif /* COMMON_CONFIG_OBSWVERSION_H_ */ diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index cd90272d..03d51888 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -13,7 +13,8 @@ enum commonClassIds: uint8_t { IMTQ_HANDLER, //IMTQ RW_HANDLER, //RWHA STR_HANDLER, //STRH - PLOC_MPSOC_HANDLER, //PLMP + DWLPWRON_CMD, //DWLPWRON + MPSOC_TM, //MPTM PLOC_SUPERVISOR_HANDLER, //PLSV SUS_HANDLER, //SUSS CCSDS_IP_CORE_BRIDGE, //IPCI @@ -24,8 +25,13 @@ enum commonClassIds: uint8_t { PLOC_MEMORY_DUMPER, //PLMEMDUMP PDEC_HANDLER, //PDEC CCSDS_HANDLER, //CCSDS + RATE_SETTER, //RS ARCSEC_JSON_BASE, //JSONBASE NVM_PARAM_BASE, //NVMB + FILE_SYSTEM_HELPER, //FSHLP + PLOC_MPSOC_HELPER, // PLMPHLP + SA_DEPL_HANDLER, //SADPL + MPSOC_RETURN_VALUES_IF, //MPSOCRTVIF COMMON_CLASS_ID_END // [EXPORT] : [END] }; diff --git a/common/config/commonConfig.h.in b/common/config/commonConfig.h.in index c18d4bff..6d74884f 100644 --- a/common/config/commonConfig.h.in +++ b/common/config/commonConfig.h.in @@ -12,7 +12,7 @@ // because UDP packets are not allowed in the VPN // This will cause the OBSW to initialize the TMTC bridge responsible for exchanging data with the // CCSDS IP Cores. -#define OBSW_USE_TCP_BRIDGE 1 +#define OBSW_USE_TMTC_TCP_BRIDGE 1 namespace common { extern const uint16_t PUS_PACKET_ID; diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index cce3616f..a4f3319e 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -11,12 +11,9 @@ enum commonObjects: uint32_t { TMTC_BRIDGE = 0x50000300, TMTC_POLLING_TASK = 0x50000400, FILE_SYSTEM_HANDLER = 0x50000500, + SDC_MANAGER = 0x50000550, PTME = 0x50000600, - PAPB_VC0 = 0x50000700, - PAPB_VC1 = 0x50000701, - PAPB_VC2 = 0x50000702, - PAPB_VC3 = 0x50000703, - PDEC_HANDLER = 0x50000704, + PDEC_HANDLER = 0x50000700, CCSDS_HANDLER = 0x50000800, /* 0x43 ('C') for Controllers */ @@ -29,6 +26,7 @@ enum commonObjects: uint32_t { PDU1_HANDLER = 0x44250001, PDU2_HANDLER = 0x44250002, ACU_HANDLER = 0x44250003, + BPX_BATT_HANDLER = 0x44260000, TMP1075_HANDLER_1 = 0x44420004, TMP1075_HANDLER_2 = 0x44420005, MGM_0_LIS3_HANDLER = 0x44120006, @@ -39,10 +37,12 @@ enum commonObjects: uint32_t { GYRO_1_L3G_HANDLER = 0x44120111, GYRO_2_ADIS_HANDLER = 0x44120212, GYRO_3_L3G_HANDLER = 0x44120313, + PLPCDU_HANDLER = 0x44300000, IMTQ_HANDLER = 0x44140014, PLOC_MPSOC_HANDLER = 0x44330015, PLOC_SUPERVISOR_HANDLER = 0x44330016, + PLOC_SUPERVISOR_HELPER = 0x44330017, /** * Not yet specified which pt1000 will measure which device/location in the satellite. @@ -65,22 +65,20 @@ enum commonObjects: uint32_t { RTD_IC_17 = 0x44420030, RTD_IC_18 = 0x44420031, - SUS_1 = 0x44120032, - SUS_2 = 0x44120033, - SUS_3 = 0x44120034, - SUS_4 = 0x44120035, - SUS_5 = 0x44120036, - SUS_6 = 0x44120037, - SUS_7 = 0x44120038, - SUS_8 = 0x44120039, - SUS_9 = 0x44120040, - SUS_10 = 0x44120041, - SUS_11 = 0x44120042, - SUS_12 = 0x44120043, - SUS_13 = 0x44120044, + SUS_0 = 0x44120032, + SUS_1 = 0x44120033, + SUS_2 = 0x44120034, + SUS_3 = 0x44120035, + SUS_4 = 0x44120036, + SUS_5 = 0x44120037, + SUS_6 = 0x44120038, + SUS_7 = 0x44120039, + SUS_8 = 0x44120040, + SUS_9 = 0x44120041, + SUS_10 = 0x44120042, + SUS_11 = 0x44120043, - GPS0_HANDLER = 0x44130045, - GPS1_HANDLER = 0x44130146, + GPS_CONTROLLER = 0x44130045, RW1 = 0x44120047, RW2 = 0x44120148, @@ -91,7 +89,15 @@ enum commonObjects: uint32_t { PLOC_UPDATER = 0x44330000, PLOC_MEMORY_DUMPER = 0x44330001, - STR_HELPER = 0x44330002 + STR_HELPER = 0x44330002, + PLOC_MPSOC_HELPER = 0x44330003, + AXI_PTME_CONFIG = 44330004, + PTME_CONFIG = 44330005, + + // 0x73 ('s') for assemblies and system/subsystem components + ACS_BOARD_ASS = 0x73000001, + SUS_BOARD_ASS = 0x73000002, + TCS_BOARD_ASS = 0x73000003 }; } diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index 55a4bed4..a93986a1 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -19,6 +19,11 @@ enum: uint8_t { PLOC_MEMORY_DUMPER = 118, PDEC_HANDLER = 119, STR_HELPER = 120, + PLOC_MPSOC_HELPER = 121, + PL_PCDU_HANDLER = 122, + ACS_BOARD_ASS = 123, + SUS_BOARD_ASS = 124, + TCS_BOARD_ASS = 125, COMMON_SUBSYSTEM_ID_END }; } diff --git a/common/config/devConf.h b/common/config/devConf.h index 78681ec7..7e09b50f 100644 --- a/common/config/devConf.h +++ b/common/config/devConf.h @@ -23,9 +23,18 @@ static constexpr uint32_t DEFAULT_L3G_SPEED = 976'000; static constexpr uint32_t L3G_TRANSITION_DELAY = 5000; static constexpr spi::SpiModes DEFAULT_L3G_MODE = spi::SpiModes::MODE_3; -static constexpr uint32_t DEFAULT_MAX_1227_SPEED = 3'900'000; +/** + * Some MAX1227 could not be reached with frequencies around 4 MHz. Maybe this is caused by + * the decoder and buffer circuits. Thus frequency is here defined to 1 MHz. + */ +static const uint32_t SUS_MAX1227_SPI_FREQ = 976'000; +static constexpr spi::SpiModes SUS_MAX_1227_MODE = spi::SpiModes::MODE_3; + +static constexpr uint32_t DEFAULT_MAX_1227_SPEED = 976'000; static constexpr spi::SpiModes DEFAULT_MAX_1227_MODE = spi::SpiModes::MODE_3; +static constexpr uint32_t PL_PCDU_MAX_1227_SPEED = 976'000; + static constexpr uint32_t DEFAULT_ADIS16507_SPEED = 976'000; static constexpr spi::SpiModes DEFAULT_ADIS16507_MODE = spi::SpiModes::MODE_3; @@ -44,7 +53,7 @@ static constexpr uint32_t SYRLINKS_BAUD = 38400; static constexpr uint32_t GNSS_BAUD = 9600; static constexpr uint32_t PLOC_MPSOC_BAUD = 115200; static constexpr uint32_t PLOC_SUPERVISOR_BAUD = 115200; -static constexpr uint32_t STAR_TRACKER_BAUD = 115200; +static constexpr uint32_t STAR_TRACKER_BAUD = 921600; } diff --git a/common/config/devices/gpioIds.h b/common/config/devices/gpioIds.h new file mode 100644 index 00000000..199439cc --- /dev/null +++ b/common/config/devices/gpioIds.h @@ -0,0 +1,130 @@ +#ifndef FSFWCONFIG_DEVICES_GPIOIDS_H_ +#define FSFWCONFIG_DEVICES_GPIOIDS_H_ + +#include + +namespace gpioIds { +enum gpioId_t { + HEATER_0, + HEATER_1, + HEATER_2, + HEATER_3, + HEATER_4, + HEATER_5, + HEATER_6, + HEATER_7, + DEPLSA1, + DEPLSA2, + + MGM_0_LIS3_CS, + MGM_1_RM3100_CS, + GYRO_0_ADIS_CS, + GYRO_1_L3G_CS, + GYRO_2_ADIS_CS, + GYRO_3_L3G_CS, + MGM_2_LIS3_CS, + MGM_3_RM3100_CS, + + GNSS_0_NRESET, + GNSS_1_NRESET, + GNSS_0_ENABLE, + GNSS_1_ENABLE, + GNSS_SELECT, + + GYRO_0_ENABLE, + GYRO_2_ENABLE, + + TEST_ID_0, + TEST_ID_1, + + RTD_IC_3, + RTD_IC_4, + RTD_IC_5, + RTD_IC_6, + RTD_IC_7, + RTD_IC_8, + RTD_IC_9, + RTD_IC_10, + RTD_IC_11, + RTD_IC_12, + RTD_IC_13, + RTD_IC_14, + RTD_IC_15, + RTD_IC_16, + RTD_IC_17, + RTD_IC_18, + + CS_SUS_0, + CS_SUS_1, + CS_SUS_2, + CS_SUS_3, + CS_SUS_4, + CS_SUS_5, + CS_SUS_6, + CS_SUS_7, + CS_SUS_8, + CS_SUS_9, + CS_SUS_10, + CS_SUS_11, + + SPI_MUX_BIT_0, + SPI_MUX_BIT_1, + SPI_MUX_BIT_2, + SPI_MUX_BIT_3, + SPI_MUX_BIT_4, + SPI_MUX_BIT_5, + + CS_RAD_SENSOR, + ENABLE_RADFET, + + PAPB_BUSY_N, + PAPB_EMPTY, + + EN_RW1, + EN_RW2, + EN_RW3, + EN_RW4, + + CS_RW1, + CS_RW2, + CS_RW3, + CS_RW4, + + EN_RW_CS, + + SPI_MUX, + + VC0_PAPB_EMPTY, + VC0_PAPB_BUSY, + VC1_PAPB_EMPTY, + VC1_PAPB_BUSY, + VC2_PAPB_EMPTY, + VC2_PAPB_BUSY, + VC3_PAPB_EMPTY, + VC3_PAPB_BUSY, + + PDEC_RESET, + + RS485_EN_TX_DATA, + RS485_EN_TX_CLOCK, + RS485_EN_RX_DATA, + RS485_EN_RX_CLOCK, + + BIT_RATE_SEL, + + PLPCDU_ENB_VBAT0, + PLPCDU_ENB_VBAT1, + PLPCDU_ENB_DRO, + PLPCDU_ENB_X8, + PLPCDU_ENB_TX, + PLPCDU_ENB_HPA, + PLPCDU_ENB_MPA, + PLPCDU_ADC_CS, + + ENABLE_MPSOC_UART, + ENABLE_SUPV_UART + +}; +} + +#endif /* FSFWCONFIG_DEVICES_GPIOIDS_H_ */ diff --git a/common/config/devices/powerSwitcherList.h b/common/config/devices/powerSwitcherList.h index 45428a2e..27c90e18 100644 --- a/common/config/devices/powerSwitcherList.h +++ b/common/config/devices/powerSwitcherList.h @@ -3,58 +3,67 @@ #include "OBSWConfig.h" +#include #include namespace pcduSwitches { - /* Switches are uint8_t datatype and go from 0 to 255 */ - enum SwitcherList: uint8_t { - Q7S, - PAYLOAD_PCDU_CH1, - RW, - TCS_BOARD_8V_HEATER_IN, - SUS_REDUNDANT, - DEPLOYMENT_MECHANISM, - PAYLOAD_PCDU_CH6, - ACS_BOARD_SIDE_B, - PAYLOAD_CAMERA, - TCS_BOARD_3V3, - SYRLINKS, - STAR_TRACKER, - MGT, - SUS_NOMINAL, - SOLAR_CELL_EXP, - PLOC, - ACS_BOARD_SIDE_A, - NUMBER_OF_SWITCHES - }; +/* Switches are uint8_t datatype and go from 0 to 255 */ +enum Switches: uint8_t { + PDU1_CH0_TCS_BOARD_3V3, + PDU1_CH1_SYRLINKS_12V, + PDU1_CH2_STAR_TRACKER_5V, + PDU1_CH3_MGT_5V, + PDU1_CH4_SUS_NOMINAL_3V3, + PDU1_CH5_SOLAR_CELL_EXP_5V, + PDU1_CH6_PLOC_12V, + PDU1_CH7_ACS_A_SIDE_3V3, + PDU1_CH8_UNOCCUPIED, - static const uint8_t ON = 1; - static const uint8_t OFF = 0; + PDU2_CH0_Q7S, + PDU2_CH1_PL_PCDU_BATT_0_14V8, + PDU2_CH2_RW_5V, + PDU2_CH3_TCS_BOARD_HEATER_IN_8V, + PDU2_CH4_SUS_REDUNDANT_3V3, + PDU2_CH5_DEPLOYMENT_MECHANISM_8V, + PDU2_CH6_PL_PCDU_BATT_1_14V8, + PDU2_CH7_ACS_BOARD_SIDE_B_3V3, + PDU2_CH8_PAYLOAD_CAMERA, + NUMBER_OF_SWITCHES +}; - /* Output states after reboot of the PDUs */ - static const uint8_t INIT_STATE_Q7S = ON; - static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; - static const uint8_t INIT_STATE_RW = OFF; -#if BOARD_TE0720 == 1 - /* Because the TE0720 is not connected to the PCDU, this switch is always on */ - static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; +static const uint8_t ON = 1; +static const uint8_t OFF = 0; + +// Output states after reboot of the PDUs + +const std::array INIT_SWITCH_STATES = { + // PDU 1 +// Because the TE0720 is not connected to the PCDU, this switch is always on +#ifdef TE0720_1CFA + ON, #else - static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; + OFF, #endif - static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; - static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; - static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; - static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; - static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; - static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; - static const uint8_t INIT_STATE_SYRLINKS = OFF; - static const uint8_t INIT_STATE_STAR_TRACKER = OFF; - static const uint8_t INIT_STATE_MGT = OFF; - static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; - static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; - static const uint8_t INIT_STATE_PLOC = OFF; - static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + + // PDU 2 + ON, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF +}; } - #endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */ diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h new file mode 100644 index 00000000..db430540 --- /dev/null +++ b/common/config/eive/definitions.h @@ -0,0 +1,25 @@ +#ifndef COMMON_CONFIG_DEFINITIONS_H_ +#define COMMON_CONFIG_DEFINITIONS_H_ + +#include + +namespace config { + +static constexpr uint32_t PL_PCDU_TRANSITION_TIMEOUT_MS = 20 * 60 * 1000; +static constexpr uint32_t LONGEST_MODE_TIMEOUT_SECONDS = PL_PCDU_TRANSITION_TIMEOUT_MS / 1000; + +/* Add mission configuration flags here */ +static constexpr uint32_t OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE = 50; +static constexpr uint32_t PLOC_UPDATER_QUEUE_SIZE = 50; +static constexpr uint32_t STR_IMG_HELPER_QUEUE_SIZE = 50; + +static constexpr uint8_t LIVE_TM = 0; + +/* Limits for filename and path checks */ +static constexpr uint32_t MAX_PATH_SIZE = 100; +static constexpr uint32_t MAX_FILENAME_SIZE = 50; + +} + + +#endif /* COMMON_CONFIG_DEFINITIONS_H_ */ diff --git a/common/config/lwgps_opts.h b/common/config/lwgps_opts.h index 20632d6f..2be39f1d 100644 --- a/common/config/lwgps_opts.h +++ b/common/config/lwgps_opts.h @@ -41,4 +41,8 @@ * copy & replace here settings you want to change values */ +#ifndef __DOXYGEN__ +#define __DOXYGEN__ 0 +#endif + #endif /* LWGPS_HDR_OPTS_H */ diff --git a/fsfw b/fsfw index b98c85d3..532607bf 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit b98c85d33fd79853e674f75dadd0a082a962aee4 +Subproject commit 532607bf8f0e5b62788e5fb8a33ef5ae3a29aeb5 diff --git a/generators/.gitignore b/generators/.gitignore index 181d655f..889fd273 100644 --- a/generators/.gitignore +++ b/generators/.gitignore @@ -1 +1,2 @@ .~lock* +/venv diff --git a/generators/.run/events.run.xml b/generators/.run/events.run.xml index 18f71033..6bc73c96 100644 --- a/generators/.run/events.run.xml +++ b/generators/.run/events.run.xml @@ -12,7 +12,7 @@