diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8323fdea8..32dc29f9b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -146,7 +146,7 @@ jobs: ln -s $(brew --prefix llvm)/bin/clang-apply-replacements /usr/local/bin ln -s $(brew --prefix llvm)/bin/run-clang-tidy.py /usr/local/bin - name: Prepare run - run: cd build && cmake .. && make volk_gnsssdr_module gtest-1.14.0 core_monitor core_libs pvt_libs + run: cd build && cmake .. && make volk_gnsssdr_module gtest-1.15.2 core_monitor core_libs pvt_libs - name: run clang-tidy run: cd build && /opt/homebrew/opt/llvm/bin/run-clang-tidy -fix - name: check diff --git a/.gitignore b/.gitignore index 007b9ab0c..a876bf1c1 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,10 @@ cmake-build-debug/ .vscode/ .vs/ Testing/ + +GSDR* +PVT_* +HAS_* +gnss_sdr_pvt.nmea +build-debug/ +build-release/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f0fbcae71..ffa66cf5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ list(APPEND CMAKE_MODULE_PATH ${GNSSSDR_SOURCE_DIR}/cmake/Modules) # Enable them at the command line by doing 'cmake -DENABLE_XXX=ON ..' ################################################################################ include(FeatureSummary) +include(GnsssdrLibPaths) # Support of optional RF front-ends option(ENABLE_UHD "Enable the use of UHD (driver for all USRP devices)" ON) @@ -44,6 +45,10 @@ option(ENABLE_AD936X_SDR "Enable the use of AD936X front-ends using libiio, requ option(ENABLE_AD9361 "Enable the use of AD9361 direct to FPGA hardware, requires libiio" OFF) +option(ENABLE_MAX2771 "Enable the use of MAX2771 direct to FPGA hardware, requires the spidev driver" OFF) + +option(ENABLE_DMA_PROXY "Enable the use of the DMA direct to FPGA hardware, requires the DMA Proxy driver" OFF) + option(ENABLE_RAW_UDP "Enable the use of high-optimized custom UDP packet sample source, requires libpcap" OFF) option(ENABLE_FLEXIBAND "Enable the use of the signal source adater for the Teleorbit Flexiband GNU Radio driver" OFF) @@ -351,9 +356,9 @@ set(GNSSSDR_ARMADILLO_LOCAL_VERSION "14.0.x") set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2") set(GNSSSDR_GLOG_LOCAL_VERSION "0.7.1") set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.27") -set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "27.2") +set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "27.3") set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.14") -set(GNSSSDR_GTEST_LOCAL_VERSION "1.14.0") +set(GNSSSDR_GTEST_LOCAL_VERSION "1.15.2") set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "origin/master") set(GNSSSDR_GNSSTK_LOCAL_VERSION "14.3.0") set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.8.5") @@ -3352,6 +3357,107 @@ endif() +##################################################################### +# Check signal sources related to FPGA only. +##################################################################### +if(ENABLE_MAX2771 AND NOT ENABLE_FPGA) + message(STATUS "The SPIdev driver is enabled, but the FPGA is not enabled. The FPGA is required when using the SPIdev driver.") + if(ENABLE_PACKAGING) + set(ENABLE_MAX2771 OFF) + else() + message(FATAL_ERROR "ENABLE_MAX2771 can only be set when ENABLE_FPGA is also set.") + endif() +endif() +if(ENABLE_DMA_PROXY AND NOT ENABLE_FPGA) + message(STATUS "The DMA Proxy driver is enabled, but the FPGA is not enabled. The FPGA is required when using the DMA Proxy driver.") + if(ENABLE_PACKAGING) + set(ENABLE_DMA_PROXY OFF) + else() + message(FATAL_ERROR "ENABLE_DMA_PROXY can only be set when ENABLE_FPGA is also set.") + endif() +endif() + + + +##################################################################### +# spidev driver - OPTIONAL +# Linux kernel driver that provides user-space access to Serial +# Peripheral Interface) +##################################################################### +if(ENABLE_MAX2771) + if(DEFINED ENV{SDKTARGETSYSROOT}) + set(TARGET_ROOTFS_PATH $ENV{SDKTARGETSYSROOT}) + else() + set(TARGET_ROOTFS_PATH "") + endif() + find_program(STRINGS_EXECUTABLE strings) + if(NOT STRINGS_EXECUTABLE) + message(STATUS "The 'strings' command could not be found. See https://www.gnu.org/software/binutils/") + message(STATUS " You can try to install it by typing:") + if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU") + if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + message(STATUS " sudo yum install binutils") + elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") + message(STATUS " sudo zypper install binutils") + else() + message(STATUS " sudo apt-get install binutils") + endif() + endif() + message(FATAL_ERROR "Binutils are required to build GNSS-SDR for SoC FPGA devices using the MAX2771 option.") + endif() + set(DTB_FILE "${TARGET_ROOTFS_PATH}/boot/devicetree/system-top.dtb") + if(EXISTS "${DTB_FILE}") + message(STATUS "Found DTB file: ${DTB_FILE}") + # Run the strings command and grep for "spidev" + execute_process( + COMMAND ${STRINGS_EXECUTABLE} ${DTB_FILE} + COMMAND grep "spidev" + OUTPUT_VARIABLE GREP_OUTPUT + RESULT_VARIABLE GREP_RESULT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(GREP_RESULT EQUAL 0) + message(STATUS "Found spidev-compatible peripheral in ${DTB_FILE}.") + else() + message(STATUS "SPIdev driver not found, its installation is required.") + if(ENABLE_PACKAGING) + set(ENABLE_MAX2771 OFF) + else() + message(FATAL_ERROR "SPIdev driver is required for building gnss-sdr with -DENABLE_MAX2271=ON.") + endif() + endif() + else() + message(FATAL_ERROR "The device tree (DTB) file ${DTB_FILE} cannot be found.") + endif() +endif() + + + +##################################################################### +# DMA Proxy driver - OPTIONAL +# Simplified and efficient interface for user-space applications +# to leverage DMA capabilities for Xilinx FPGA and SoC systems +##################################################################### +if(ENABLE_DMA_PROXY) + if(DEFINED ENV{SDKTARGETSYSROOT}) + set(TARGET_ROOTFS_PATH $ENV{SDKTARGETSYSROOT}) + else() + set(TARGET_ROOTFS_PATH "") + endif() + set(DMA_PROXY_FILE "${TARGET_ROOTFS_PATH}/lib/modules/5.10.0-xilinx-v2021.2/extra/dma-proxy.ko") + if(EXISTS "${DMA_PROXY_FILE}") + message(STATUS "Found dma-proxy.ko file: ${DMA_PROXY_FILE}") + else() + if(ENABLE_PACKAGING) + set(ENABLE_DMA_PROXY OFF) + else() + message(FATAL_ERROR "DMA Proxy driver is required for building gnss-sdr with -DENABLE_DMA_PROXY=ON.") + endif() + endif() +endif() + + + ############################################## # TELEORBIT FLEXIBAND FRONTEND - OPTIONAL ############################################## @@ -3556,6 +3662,8 @@ add_feature_info(ENABLE_LIMESDR ENABLE_LIMESDR "Enables Limesdr_Signal_Source. R add_feature_info(ENABLE_FMCOMMS2 ENABLE_FMCOMMS2 "Enables Fmcomms2_Signal_Source for FMCOMMS2/3/4 devices. Requires gr-iio and libad9361-dev.") add_feature_info(ENABLE_PLUTOSDR ENABLE_PLUTOSDR "Enables Plutosdr_Signal_Source for using ADALM-PLUTO boards. Requires gr-iio.") add_feature_info(ENABLE_AD9361 ENABLE_AD9361 "Enables Ad9361_Fpga_Signal_Source for devices with the AD9361 chipset. Requires libiio and libad9361-dev.") +add_feature_info(ENABLE_MAX2771 ENABLE_MAX2771 "Enables FPGA_MAX2771_EVKIT_Signal_Source for devices with the MAX2771 chipset. Requires the spidev driver") +add_feature_info(ENABLE_DMA_PROXY ENABLE_DMA_PROXY "Enables DMA Signal_Source. Requires the DMA Proxy driver") add_feature_info(ENABLE_AD936X_SDR ENABLE_AD936X_SDR "Enables Ad936x_Iio_Signal_Source to access AD936X front-ends using libiio. Requires libiio and libad9361-dev.") add_feature_info(ENABLE_RAW_UDP ENABLE_RAW_UDP "Enables Custom_UDP_Signal_Source for custom UDP packet sample source. Requires libpcap.") add_feature_info(ENABLE_FLEXIBAND ENABLE_FLEXIBAND "Enables Flexiband_Signal_Source for using Teleorbit's Flexiband RF front-end. Requires gr-teleorbit.") diff --git a/README.md b/README.md index b9c64d1ff..cea038c48 100644 --- a/README.md +++ b/README.md @@ -490,8 +490,8 @@ $ sudo ldconfig #### Download [GoogleTest](https://github.com/google/googletest "Googletest Homepage") ``` -$ wget https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip -$ unzip v1.14.0.zip +$ wget https://github.com/google/googletest/archive/refs/tags/v1.15.2.zip +$ unzip v1.15.2.zip ``` Please **DO NOT build or install** Google Test. Every user needs to compile @@ -515,10 +515,10 @@ downloaded resides. Just type in your terminal (or add it to your `$HOME/.bashrc` file for a permanent solution) the following line: ``` -export GTEST_DIR=/home/username/googletest-1.14.0 +export GTEST_DIR=/home/username/googletest-1.15.2 ``` -changing `/home/username/googletest-1.14.0` by the actual path where you +changing `/home/username/googletest-1.15.2` by the actual path where you unpacked Google Test. If the CMake script does not find that folder, or the environment variable is not defined, or the source code is not installed by a package, then it will download a fresh copy of the Google Test source code and diff --git a/cmake/Modules/FindCPUFEATURES.cmake b/cmake/Modules/FindCPUFEATURES.cmake index 7c25e69c2..6f4f0e58f 100644 --- a/cmake/Modules/FindCPUFEATURES.cmake +++ b/cmake/Modules/FindCPUFEATURES.cmake @@ -6,38 +6,13 @@ set(FPHSA_NAME_MISMATCHED ON) +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + find_library(CPUFEATURES_LIBRARIES NAMES cpu_features - PATHS /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + PATHS ${GNSSSDR_LIB_PATHS} ) find_path(CPUFEATURES_INCLUDE_DIR cpu_features_macros.h diff --git a/cmake/Modules/FindGFLAGS.cmake b/cmake/Modules/FindGFLAGS.cmake index 08a5056b8..cbfa07cd3 100644 --- a/cmake/Modules/FindGFLAGS.cmake +++ b/cmake/Modules/FindGFLAGS.cmake @@ -25,6 +25,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT GFLAGS_ROOT) set(GFLAGS_ROOT_USER_PROVIDED /usr/local) else() @@ -52,36 +56,7 @@ else() PATHS ${GFLAGS_ROOT_USER_PROVIDED}/lib ${GFLAGS_ROOT_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) endif() diff --git a/cmake/Modules/FindGFORTRAN.cmake b/cmake/Modules/FindGFORTRAN.cmake index 5a698ce89..26764a688 100644 --- a/cmake/Modules/FindGFORTRAN.cmake +++ b/cmake/Modules/FindGFORTRAN.cmake @@ -8,6 +8,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT GFORTRAN_ROOT) set(GFORTRAN_ROOT_USER_DEFINED /usr/lib) else() @@ -20,13 +24,12 @@ if(DEFINED ENV{GFORTRAN_ROOT}) ) endif() -set(GCC_MAJOR_SERIES 14 13 12 11 10 9 8 7 6 5) +set(GCC_MAJOR_SERIES 15 14 13 12 11 10 9 8 7 6 5) set(GCC4_SERIES 4.9.1 4.9 4.8.3 4.8.1 4.7.2 4.7 4.8.2 4.8 4.7 4.6 4.5 4.4.4 4.4) set(GCC_SERIES ${GCC_MAJOR_SERIES} ${GCC4_SERIES}) find_library(GFORTRAN NAMES gfortran PATHS ${GFORTRAN_ROOT_USER_DEFINED} - /usr/lib64 /usr/lib/gcc/x86_64-linux-gnu # Debian /usr/lib/gcc/i386-linux-gnu /usr/lib/gcc/i486-linux-gnu @@ -65,35 +68,13 @@ find_library(GFORTRAN NAMES gfortran /usr/lib/gcc/x86_64-suse-linux /usr/lib/gcc/armv6hl-suse-linux-gnueabi /usr/lib/gcc/armv7hl-suse-linux-gnueabi + /usr/lib/gcc/loongarch64-linux-gnu /usr/lib64/gcc/aarch64-suse-linux /usr/lib64/gcc/powerpc64-suse-linux /usr/lib64/gcc/powerpc64le-suse-linux /usr/lib64/gcc/riscv64-suse-linux /usr/lib64/gcc/s390x-suse-linux - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/aarch64-linux-gnu - /usr/lib/i386-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /usr/local/lib/i386 + ${GNSSSDR_LIB_PATHS} PATH_SUFFIXES ${GCC_SERIES} ) diff --git a/cmake/Modules/FindGLOG.cmake b/cmake/Modules/FindGLOG.cmake index 6c506643e..8f6c880a0 100644 --- a/cmake/Modules/FindGLOG.cmake +++ b/cmake/Modules/FindGLOG.cmake @@ -24,6 +24,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -45,36 +49,7 @@ macro(_FIND_GLOG_LIBRARIES _var) NAMES ${ARGN} HINTS ${PC_GLOG_LIBDIR} PATHS ${LIB_PATHS} - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ${GLOG_ROOT}/lib $ENV{GLOG_ROOT}/lib ${GLOG_ROOT}/lib64 diff --git a/cmake/Modules/FindGNURADIO.cmake b/cmake/Modules/FindGNURADIO.cmake index 9855ddc29..cfaf51764 100644 --- a/cmake/Modules/FindGNURADIO.cmake +++ b/cmake/Modules/FindGNURADIO.cmake @@ -12,6 +12,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -105,36 +109,7 @@ function(GR_MODULE EXTVAR PCNAME INCFILE LIBFILE) HINTS ${PC_LIBDIR} PATHS ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/lib ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) list(APPEND ${LIBVAR_NAME} ${${LIBVAR_NAME}_${libname}}) endforeach() @@ -314,35 +289,7 @@ if(GNURADIO_VERSION VERSION_GREATER 3.8.99) HINTS ${PC_GNURADIO_IIO_LIBDIR} PATHS ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/lib ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) if(GNURADIO_IIO_LIBRARIES) diff --git a/cmake/Modules/FindGRIIO.cmake b/cmake/Modules/FindGRIIO.cmake index 1abd5caf4..6a4352fc0 100644 --- a/cmake/Modules/FindGRIIO.cmake +++ b/cmake/Modules/FindGRIIO.cmake @@ -13,6 +13,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -70,36 +74,7 @@ find_library(IIO_LIBRARIES HINTS ${PC_IIO_LIBDIR} PATHS ${GRIIO_ROOT_USER_DEFINED}/lib ${GRIIO_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i686-gnu - /usr/lib/i686-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i686-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/sh4-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindGRLIMESDR.cmake b/cmake/Modules/FindGRLIMESDR.cmake index 2fb60cb3f..a0ca9a565 100644 --- a/cmake/Modules/FindGRLIMESDR.cmake +++ b/cmake/Modules/FindGRLIMESDR.cmake @@ -31,6 +31,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -70,36 +74,7 @@ find_library(GRLIMESDR_LIBRARIES PATHS ${GRLIMESDR_ROOT_USER_DEFINED}/lib ${GRLIMESDR_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/riscv64-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindGROSMOSDR.cmake b/cmake/Modules/FindGROSMOSDR.cmake index 22ee7d51e..15a36c32b 100644 --- a/cmake/Modules/FindGROSMOSDR.cmake +++ b/cmake/Modules/FindGROSMOSDR.cmake @@ -31,6 +31,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -70,36 +74,7 @@ find_library(GROSMOSDR_LIBRARIES PATHS ${GROSMOSDR_ROOT_USER_DEFINED}/lib ${GROSMOSDR_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/riscv64-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindLIBAD9361.cmake b/cmake/Modules/FindLIBAD9361.cmake index e1ff8e4a3..175a81af2 100644 --- a/cmake/Modules/FindLIBAD9361.cmake +++ b/cmake/Modules/FindLIBAD9361.cmake @@ -13,6 +13,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -49,36 +53,7 @@ find_library(LIBAD9361_LIBRARIES HINTS ${PC_LIBAD9361_LIBDIR} PATHS ${LIBAD9361_ROOT_USER_DEFINED}/lib ${LIBAD9361_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i686-gnu - /usr/lib/i686-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i686-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/sh4-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} /Library/Frameworks/ad9361.framework ) diff --git a/cmake/Modules/FindLIBIIO.cmake b/cmake/Modules/FindLIBIIO.cmake index 44f4d367e..add9215de 100644 --- a/cmake/Modules/FindLIBIIO.cmake +++ b/cmake/Modules/FindLIBIIO.cmake @@ -13,6 +13,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -51,36 +55,7 @@ find_library( HINTS ${PC_LIBIIO_LIBDIR} PATHS ${LIBIIO_ROOT_USER_DEFINED}/lib ${LIBIIO_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i686-gnu - /usr/lib/i686-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i686-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/sh4-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} /Library/Frameworks/iio.framework/ ) diff --git a/cmake/Modules/FindLIBUNWIND.cmake b/cmake/Modules/FindLIBUNWIND.cmake index f2c88b569..b5c6a68a8 100644 --- a/cmake/Modules/FindLIBUNWIND.cmake +++ b/cmake/Modules/FindLIBUNWIND.cmake @@ -17,6 +17,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + find_path(LIBUNWIND_INCLUDE_DIR NAMES libunwind.h @@ -41,6 +45,7 @@ find_library(LIBUNWIND_GENERIC_LIBRARY PATHS "${LIBUNWIND_ROOT}/lib" "${LIBUNWIND_ROOT}/lib64" + ${GNSSSDR_LIB_PATHS} ) if(LIBUNWIND_INCLUDE_DIR) diff --git a/cmake/Modules/FindLOG4CPP.cmake b/cmake/Modules/FindLOG4CPP.cmake index 95a14cf62..f351ebf3a 100644 --- a/cmake/Modules/FindLOG4CPP.cmake +++ b/cmake/Modules/FindLOG4CPP.cmake @@ -19,6 +19,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -74,35 +78,7 @@ find_library(LOG4CPP_LIBRARY HINTS ${PC_LOG4CPP_LIBDIR} PATHS ${LOG4CPP_ROOT_USER_PROVIDED}/lib ${LOG4CPP_ROOT_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) if(LOG4CPP_INCLUDE_DIR AND LOG4CPP_LIBRARY) diff --git a/cmake/Modules/FindMATIO.cmake b/cmake/Modules/FindMATIO.cmake index d9a6cebd2..73f8d053d 100644 --- a/cmake/Modules/FindMATIO.cmake +++ b/cmake/Modules/FindMATIO.cmake @@ -55,6 +55,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT MATIO_ROOT) set(MATIO_ROOT_USER_DEFINED /usr) else() @@ -85,33 +89,7 @@ find_library(MATIO_LIBRARY PATHS ${MATIO_ROOT_USER_DEFINED}/lib ${MATIO_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/alpha-linux-gnu - /usr/lib/x86_64-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib DOC "The MATIO library" ) diff --git a/cmake/Modules/FindORC.cmake b/cmake/Modules/FindORC.cmake index b6a4ba364..600d0ac35 100644 --- a/cmake/Modules/FindORC.cmake +++ b/cmake/Modules/FindORC.cmake @@ -13,6 +13,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -65,26 +69,7 @@ find_path(ORC_LIBRARY_DIR ${ORC_ROOT_USER_PROVIDED}/lib64 ${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_INSTALL_PREFIX}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) find_library(ORC_LIB orc-0.4 @@ -93,26 +78,7 @@ find_library(ORC_LIB orc-0.4 ${ORC_ROOT_USER_PROVIDED}/lib64 ${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_INSTALL_PREFIX}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) find_library(ORC_LIBRARY_STATIC ${CMAKE_STATIC_LIBRARY_PREFIX}orc-0.4${CMAKE_STATIC_LIBRARY_SUFFIX} diff --git a/cmake/Modules/FindPCAP.cmake b/cmake/Modules/FindPCAP.cmake index 39a7aff15..2a3db3aff 100644 --- a/cmake/Modules/FindPCAP.cmake +++ b/cmake/Modules/FindPCAP.cmake @@ -23,6 +23,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -88,33 +92,7 @@ else() ${PC_PCAP_LIBDIR} PATHS ${PCAP_ROOT_USER_PROVIDED}/lib - /usr/lib - /usr/lib64 - /usr/lib/alpha-linux-gnu - /usr/lib/x86_64-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) endif() diff --git a/cmake/Modules/FindPUGIXML.cmake b/cmake/Modules/FindPUGIXML.cmake index 5f7f5dcb2..4ff6419cc 100644 --- a/cmake/Modules/FindPUGIXML.cmake +++ b/cmake/Modules/FindPUGIXML.cmake @@ -20,6 +20,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -66,36 +70,9 @@ find_library(PUGIXML_LIBRARY ${PUGIXML_ROOT_USER_DEFINED}/lib64/pugixml-${PC_PUGIXML_VERSION} ${PUGIXML_ROOT_USER_DEFINED}}/lib/pugixml-1.9 ${PUGIXML_ROOT_USER_DEFINED}/lib64/pugixml-1.9 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/i386-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/local/lib - /usr/local/lib64 + ${GNSSSDR_LIB_PATHS} /usr/local/lib/pugixml-${PC_PUGIXML_VERSION} /usr/local/lib/pugixml-1.9 - /opt/local/lib ) # Support the REQUIRED and QUIET arguments, and set PUGIXML_FOUND if found. diff --git a/cmake/Modules/FindUHD.cmake b/cmake/Modules/FindUHD.cmake index a6ed654a3..d30313535 100644 --- a/cmake/Modules/FindUHD.cmake +++ b/cmake/Modules/FindUHD.cmake @@ -16,6 +16,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -60,36 +64,7 @@ find_library(UHD_LIBRARIES HINTS ${PC_UHD_LIBDIR} PATHS ${UHD_ROOT_USER_PROVIDED}/lib ${UHD_ROOT_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindVOLK.cmake b/cmake/Modules/FindVOLK.cmake index bda662186..2247f8247 100644 --- a/cmake/Modules/FindVOLK.cmake +++ b/cmake/Modules/FindVOLK.cmake @@ -16,6 +16,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -58,35 +62,7 @@ find_library(VOLK_LIBRARIES HINTS ${PC_VOLK_LIBDIR} PATHS ${VOLK_ROOT_USER_PROVIDED}/lib ${VOLK_ROOT_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindZEROMQ.cmake b/cmake/Modules/FindZEROMQ.cmake index 6579d9ed7..d42a68d2d 100644 --- a/cmake/Modules/FindZEROMQ.cmake +++ b/cmake/Modules/FindZEROMQ.cmake @@ -13,6 +13,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrLibPaths) +endif() + if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() @@ -29,33 +33,7 @@ find_path(ZEROMQ_INCLUDE_DIRS find_library(ZEROMQ_LIBRARIES NAMES zmq libzmq.so.5 ${ZEROMQ_LIBRARY_NAME} HINTS ${PC_ZEROMQ_LIBDIR} ${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_INSTALL_PREFIX}/lib64 - PATHS /usr/lib - /usr/lib64 - /usr/lib/alpha-linux-gnu - /usr/lib/x86_64-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + PATHS ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/GnsssdrLibPaths.cmake b/cmake/Modules/GnsssdrLibPaths.cmake new file mode 100644 index 000000000..9f76e362f --- /dev/null +++ b/cmake/Modules/GnsssdrLibPaths.cmake @@ -0,0 +1,43 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# SPDX-FileCopyrightText: 2011-2024 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-License-Identifier: BSD-3-Clause + +if(GNSSSDR_LIB_PATHS) + return() +endif() + +set(GNSSSDR_LIB_PATHS + /usr/lib + /usr/lib/aarch64-linux-gnu + /usr/lib/alpha-linux-gnu + /usr/lib/arm-linux-gnueabi + /usr/lib/arm-linux-gnueabihf + /usr/lib/hppa-linux-gnu + /usr/lib/hppa-linux-gnu + /usr/lib/i386-gnu + /usr/lib/i386-kfreebsd-gnu + /usr/lib/i386-linux-gnu + /usr/lib/loongarch64-linux-gnu + /usr/lib/m68k-linux-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/mipsel-linux-gnu + /usr/lib/powerpc-linux-gnu + /usr/lib/powerpc-linux-gnuspe + /usr/lib/powerpc64-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/riscv64-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/lib/sh4-linux-gnu + /usr/lib/sparc64-linux-gnu + /usr/lib/x86_64-kfreebsd-gnu + /usr/lib/x86_64-linux-gnu + /usr/lib/x86_64-linux-gnux32 + /usr/lib64 + /usr/local/lib + /usr/local/lib/i386 + /usr/local/lib64 + /opt/local/lib +) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index e7e594fb9..931e8988f 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -21,6 +21,25 @@ All notable changes to GNSS-SDR will be documented in this file. wideband device (HackRF/LimeSDR/USRP). Demonstration: https://www.youtube.com/watch?v=ZQs2sFchJ6w https://www.youtube.com/watch?v=HnZkKj9a-QM +- Add the following signal sources for use when GNSS-SDR is operating on SoC + FPGA boards (`-DENABLE_FPGA=ON`): + + - `ADRV9361_Z7035_Signal_Source_FPGA`: Analog Devices ADRV9361-Z7035 board. + - `FMCOMMS5_Signal_Source_FPGA`: FMCOMMS5 analog front-end. + - `MAX2771_EVKIT_Signal_Source_FPGA`: MAX2771 evaluation kit analog front-end. + - `DMA_Signal_Source_FPGA`: FPGA DMA working in post-processing mode. + + When building GNSS-SDR for the SoC FPGA, the following options can be passed + to CMake with possible values of `ON` or `OFF`, and their default value is + `OFF`: + + - `-DENABLE_AD9361`: Checks if the IIO driver is installed and builds the + `ADRV9361_Z7035_Signal_Source_FPGA` and the `FMCOMMS5_Signal_Source_FPGA` + sources. + - `-DENABLE_MAX2771`: Checks if the SPIdev driver is installed and builds the + `MAX2771_EVKIT_Signal_Source_FPGA` source. + - `-DENABLE_DMA_PROXY`: Checks if the DMA proxy driver is installed for + controlling the DMA in the FPGA and enables its usage. ### Improvements in Portability: diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc index 5ff357ff3..152458292 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc @@ -2254,7 +2254,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item d_gnss_observables_map_t1 = d_gnss_observables_map; // ### select the rx_time and interpolate observables at that time - if (!d_gnss_observables_map_t0.empty()) + if (!d_gnss_observables_map_t0.empty() && !d_gnss_observables_map_t1.empty()) { const auto t0_int_ms = static_cast(d_gnss_observables_map_t0.cbegin()->second.RX_time * 1000.0); const uint32_t adjust_next_obs_interval_ms = d_observable_interval_ms - t0_int_ms % d_observable_interval_ms; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h index 09829267c..b28d63422 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h @@ -66,11 +66,11 @@ public: } /*! - * \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga" + * \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA" */ inline std::string implementation() override { - return "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga"; + return "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA"; } /*! diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h index 12d38bf34..14dae0230 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h @@ -66,11 +66,11 @@ public: } /*! - * \brief Returns "Galileo_E5a_Pcps_Acquisition_Fpga" + * \brief Returns "Galileo_E5a_Pcps_Acquisition_FPGA" */ inline std::string implementation() override { - return "Galileo_E5a_Pcps_Acquisition_Fpga"; + return "Galileo_E5a_Pcps_Acquisition_FPGA"; } /*! diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h index 8ae54e46a..d67bfd4a6 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h @@ -65,7 +65,7 @@ public: } /*! - * \brief Returns "Galileo_E5b_Pcps_Acquisition_Fpga" + * \brief Returns "Galileo_E5b_Pcps_Acquisition_FPGA" */ inline std::string implementation() override { diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h index cfc483cda..2b7bfd3f9 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h @@ -67,11 +67,11 @@ public: } /*! - * \brief Returns "GPS_L1_CA_PCPS_Acquisition_Fpga" + * \brief Returns "GPS_L1_CA_PCPS_Acquisition_FPGA" */ inline std::string implementation() override { - return "GPS_L1_CA_PCPS_Acquisition_Fpga"; + return "GPS_L1_CA_PCPS_Acquisition_FPGA"; } /*! diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h index 19acec8cb..81f4d342c 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h @@ -60,11 +60,11 @@ public: } /*! - * \brief Returns "GPS_L2_M_PCPS_Acquisition_Fpga" + * \brief Returns "GPS_L2_M_PCPS_Acquisition_FPGA" */ inline std::string implementation() override { - return "GPS_L2_M_PCPS_Acquisition_Fpga"; + return "GPS_L2_M_PCPS_Acquisition_FPGA"; } inline size_t item_size() override diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h index 497ab9b90..bf2bfafcf 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h @@ -69,11 +69,11 @@ public: } /*! - * \brief Returns "GPS_L5i_PCPS_Acquisition_Fpga" + * \brief Returns "GPS_L5i_PCPS_Acquisition_FPGA" */ inline std::string implementation() override { - return "GPS_L5i_PCPS_Acquisition_Fpga"; + return "GPS_L5i_PCPS_Acquisition_FPGA"; } /*! diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index e4ead311b..0aa745101 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -37,8 +37,26 @@ if(ENABLE_AD9361) ############################################### # AD9361 DIRECT TO FPGA Hardware ############################################### - list(APPEND OPT_DRIVER_SOURCES ad9361_fpga_signal_source.cc) - list(APPEND OPT_DRIVER_HEADERS ad9361_fpga_signal_source.h) + list(APPEND OPT_DRIVER_SOURCES adrv9361_z7035_signal_source_fpga.cc) + list(APPEND OPT_DRIVER_HEADERS adrv9361_z7035_signal_source_fpga.h) + list(APPEND OPT_DRIVER_SOURCES fmcomms5_signal_source_fpga.cc) + list(APPEND OPT_DRIVER_HEADERS fmcomms5_signal_source_fpga.h) +endif() + +if(ENABLE_MAX2771) + ############################################### + # MAX2771 EVKIT DIRECT TO FPGA Hardware + ############################################### + list(APPEND OPT_DRIVER_SOURCES max2771_evkit_signal_source_fpga.cc) + list(APPEND OPT_DRIVER_HEADERS max2771_evkit_signal_source_fpga.h) +endif() + +if(ENABLE_DMA_PROXY) + ############################################### + # FPGA DMA source + ############################################### + list(APPEND OPT_DRIVER_SOURCES dma_signal_source_fpga.cc) + list(APPEND OPT_DRIVER_HEADERS dma_signal_source_fpga.h) endif() if(ENABLE_FLEXIBAND AND TELEORBIT_FOUND) diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc deleted file mode 100644 index 3a3360bed..000000000 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ /dev/null @@ -1,885 +0,0 @@ -/*! - * \file ad9361_fpga_signal_source.cc - * \brief signal source for Analog Devices front-end AD9361 connected directly - * to FPGA accelerators. - * This source implements only the AD9361 control. It is NOT compatible with - * conventional SDR acquisition and tracking blocks. - * Please use the fmcomms2 source if conventional SDR acquisition and tracking - * is selected in the configuration file. - * \authors - * - * ----------------------------------------------------------------------------- - * - * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. - * This file is part of GNSS-SDR. - * - * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) - * SPDX-License-Identifier: GPL-3.0-or-later - * - * ----------------------------------------------------------------------------- - */ - -#include "ad9361_fpga_signal_source.h" -#include "GPS_L1_CA.h" -#include "GPS_L5.h" -#include "ad9361_manager.h" -#include "command_event.h" -#include "configuration_interface.h" -#include "gnss_sdr_flags.h" -#include "gnss_sdr_string_literals.h" -#include "uio_fpga.h" -#include -#include // for std::max -#include // for std::chrono -#include // for std::floor -#include // for std::exception -#include // for open, O_WRONLY -#include // for std::ifstream -#include // for std::setprecision -#include // for std::cout -#include // for write -#include // fr std::vector - -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#include -#endif - -using namespace std::string_literals; - -Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *configuration, - const std::string &role, unsigned int in_stream, unsigned int out_stream, - Concurrent_Queue *queue __attribute__((unused))) - : SignalSourceBase(configuration, role, "Ad9361_Fpga_Signal_Source"s), - queue_(queue), - gain_mode_rx1_(configuration->property(role + ".gain_mode_rx1", default_gain_mode)), - gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)), - rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)), - filter_filename_(configuration->property(role + ".filter_filename", filter_file_)), - filename0_(configuration->property(role + ".filename", empty_string)), - rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)), - rf_gain_rx2_(configuration->property(role + ".gain_rx2", default_manual_gain_rx2)), - scale_dds_dbfs_(configuration->property(role + ".scale_dds_dbfs", -3.0)), - phase_dds_deg_(configuration->property(role + ".phase_dds_deg", 0.0)), - tx_attenuation_db_(configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db)), - freq0_(configuration->property(role + ".freq", 0)), - freq1_(configuration->property(role + ".freq1", static_cast(GPS_L5_FREQ_HZ))), - sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)), - bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)), - samples_to_skip_(0), - samples_(configuration->property(role + ".samples", static_cast(0))), - freq_dds_tx_hz_(configuration->property(role + ".freq_dds_tx_hz", uint64_t(10000))), - freq_rf_tx_hz_(configuration->property(role + ".freq_rf_tx_hz", static_cast(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_))), - tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast(500000))), - Fpass_(configuration->property(role + ".Fpass", static_cast(0.0))), - Fstop_(configuration->property(role + ".Fstop", static_cast(0.0))), - num_input_files_(1), - dma_buff_offset_pos_(0), - in_stream_(in_stream), - out_stream_(out_stream), - switch_position_(configuration->property(role + ".switch_position", 0)), - item_size_(sizeof(int8_t)), - enable_dds_lo_(configuration->property(role + ".enable_dds_lo", false)), - filter_auto_(configuration->property(role + ".filter_auto", false)), - quadrature_(configuration->property(role + ".quadrature", true)), - rf_dc_(configuration->property(role + ".rf_dc", true)), - bb_dc_(configuration->property(role + ".bb_dc", true)), - rx1_enable_(configuration->property(role + ".rx1_enable", true)), - rx2_enable_(configuration->property(role + ".rx2_enable", true)), - enable_DMA_(false), - enable_dynamic_bit_selection_(configuration->property(role + ".enable_dynamic_bit_selection", true)), - enable_ovf_check_buffer_monitor_active_(false), - dump_(configuration->property(role + ".dump", false)), -#if USE_GLOG_AND_GFLAGS - rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)), -#else - rf_shutdown_(configuration->property(role + ".rf_shutdown", absl::GetFlag(FLAGS_rf_shutdown))), -#endif - repeat_(configuration->property(role + ".repeat", false)) -{ - const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", 0.0); - const size_t header_size = configuration->property(role + ".header_size", 0); - - const bool enable_rx1_band((configuration->property("Channels_1C.count", 0) > 0) || - (configuration->property("Channels_1B.count", 0) > 0)); - const bool enable_rx2_band((configuration->property("Channels_L2.count", 0) > 0) || - (configuration->property("Channels_L5.count", 0) > 0) || - (configuration->property("Channels_5X.count", 0) > 0)); - - const uint32_t num_freq_bands = ((enable_rx1_band == true) and (enable_rx2_band == true)) ? 2 : 1; - if (freq0_ == 0) - { - // use ".freq0" - freq0_ = configuration->property(role + ".freq0", static_cast(GPS_L1_FREQ_HZ)); - } - - if (filter_auto_) - { - filter_source_ = configuration->property(role + ".filter_source", std::string("Auto")); - } - else - { - filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); - } -#if USE_GLOG_AND_GFLAGS - // override value with commandline flag, if present - if (FLAGS_signal_source != "-") - { - filename0_ = FLAGS_signal_source; - } - if (FLAGS_s != "-") - { - filename0_ = FLAGS_s; - } -#else - if (absl::GetFlag(FLAGS_signal_source) != "-") - { - filename0_ = absl::GetFlag(FLAGS_signal_source); - } - if (absl::GetFlag(FLAGS_s) != "-") - { - filename0_ = absl::GetFlag(FLAGS_s); - } -#endif - if (filename0_.empty()) - { - num_input_files_ = 2; - filename0_ = configuration->property(role + ".filename0", empty_string); - filename1_ = configuration->property(role + ".filename1", empty_string); - } - // if only one input file is specified in the configuration file then: - // if there is at least one channel assigned to frequency band 1 then the DMA transfers the samples to the L1 frequency band channels - // otherwise the DMA transfers the samples to the L2/L5 frequency band channels - // if more than one input file are specified then the DMA transfer the samples to both the L1 and the L2/L5 frequency channels. - if (filename1_.empty()) - { - if (enable_rx1_band) - { - dma_buff_offset_pos_ = 2; - } - } - else - { - dma_buff_offset_pos_ = 2; - } - - if (seconds_to_skip > 0) - { - samples_to_skip_ = static_cast(seconds_to_skip * sample_rate_) * 2; - } - if (header_size > 0) - { - samples_to_skip_ += header_size; - } - - std::string device_io_name; // Switch UIO device file - // find the uio device file corresponding to the switch. - if (find_uio_dev_file_name(device_io_name, switch_device_name, 0) < 0) - { - std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << switch_device_name << '\n'; - return; - } - - if (switch_position_ != 0 && switch_position_ != 2) - { - std::cout << "SignalSource.switch_position configuration parameter must be either 0: read from file(s) via DMA, or 2: read from AD9361\n"; - std::cout << "SignalSource.switch_position configuration parameter set to its default value switch_position=0 - read from file(s)\n"; - switch_position_ = 0; - } - - switch_fpga = std::make_shared(device_io_name); - switch_fpga->set_switch_position(switch_position_); - - if (switch_position_ == 0) // Inject file(s) via DMA - { - enable_DMA_ = true; - - if (samples_ == 0) // read all file - { - /*! - * BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File. - * A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the - * valve block - */ - std::ifstream file(filename0_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); - std::ifstream::pos_type size; - - if (file.is_open()) - { - size = file.tellg(); - DLOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size_)); - } - else - { - std::cerr << "SignalSource: Unable to open the samples file " << filename0_.c_str() << '\n'; - return; - } - std::streamsize ss = std::cout.precision(); - std::cout << std::setprecision(16); - std::cout << "Processing file " << filename0_ << ", which contains " << static_cast(size) << " [bytes]\n"; - std::cout.precision(ss); - - if (size > 0) - { - const uint64_t bytes_to_skip = samples_to_skip_ * item_size_; - const uint64_t bytes_to_process = static_cast(size) - bytes_to_skip; - samples_ = floor(static_cast(bytes_to_process) / static_cast(item_size_) - ceil(0.002 * static_cast(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms - } - - if (!filename1_.empty()) - { - std::ifstream file(filename1_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); - std::ifstream::pos_type size; - - if (file.is_open()) - { - size = file.tellg(); - DLOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size_)); - } - else - { - std::cerr << "SignalSource: Unable to open the samples file " << filename1_.c_str() << '\n'; - return; - } - std::streamsize ss = std::cout.precision(); - std::cout << std::setprecision(16); - std::cout << "Processing file " << filename1_ << ", which contains " << static_cast(size) << " [bytes]\n"; - std::cout.precision(ss); - - int64_t samples_rx2 = 0; - if (size > 0) - { - const uint64_t bytes_to_skip = samples_to_skip_ * item_size_; - const uint64_t bytes_to_process = static_cast(size) - bytes_to_skip; - samples_rx2 = floor(static_cast(bytes_to_process) / static_cast(item_size_) - ceil(0.002 * static_cast(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms - } - samples_ = std::min(samples_, samples_rx2); - } - } - - CHECK(samples_ > 0) << "File does not contain enough samples to process."; - double signal_duration_s = (static_cast(samples_) * (1 / static_cast(sample_rate_))) / 2.0; - - DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; - std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n"; - - if (filename1_.empty()) - { - DLOG(INFO) << "File source filename " << filename0_; - } - else - { - DLOG(INFO) << "File source filename rx1 " << filename0_; - DLOG(INFO) << "File source filename rx2 " << filename1_; - } - DLOG(INFO) << "Samples " << samples_; - DLOG(INFO) << "Sampling frequency " << sample_rate_; - DLOG(INFO) << "Item type " << std::string("ibyte"); - DLOG(INFO) << "Item size " << item_size_; - DLOG(INFO) << "Repeat " << repeat_; - } - if (switch_position_ == 2) // Real-time via AD9361 - { - std::cout << "Sample rate: " << sample_rate_ << " Sps\n"; - - enable_ovf_check_buffer_monitor_active_ = false; // check buffer overflow and buffer monitor disabled by default - - // some basic checks - if ((rf_port_select_ != "A_BALANCED") && (rf_port_select_ != "B_BALANCED") && (rf_port_select_ != "A_N") && (rf_port_select_ != "B_N") && (rf_port_select_ != "B_P") && (rf_port_select_ != "C_N") && (rf_port_select_ != "C_P") && (rf_port_select_ != "TX_MONITOR1") && (rf_port_select_ != "TX_MONITOR2") && (rf_port_select_ != "TX_MONITOR1_2")) - { - std::cout << "Configuration parameter rf_port_select should take one of these values:\n"; - std::cout << " A_BALANCED, B_BALANCED, A_N, B_N, B_P, C_N, C_P, TX_MONITOR1, TX_MONITOR2, TX_MONITOR1_2\n"; - std::cout << "Error: provided value rf_port_select=" << rf_port_select_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value rf_port_select=" << default_rf_port_select << '\n'; - rf_port_select_ = default_rf_port_select; - LOG(WARNING) << "Invalid configuration value for rf_port_select parameter. Set to rf_port_select=" << default_rf_port_select; - } - - if ((gain_mode_rx1_ != "manual") && (gain_mode_rx1_ != "slow_attack") && (gain_mode_rx1_ != "fast_attack") && (gain_mode_rx1_ != "hybrid")) - { - std::cout << "Configuration parameter gain_mode_rx1 should take one of these values:\n"; - std::cout << " manual, slow_attack, fast_attack, hybrid\n"; - std::cout << "Error: provided value gain_mode_rx1=" << gain_mode_rx1_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value gain_mode_rx1=" << default_gain_mode << '\n'; - gain_mode_rx1_ = default_gain_mode; - LOG(WARNING) << "Invalid configuration value for gain_mode_rx1 parameter. Set to gain_mode_rx1=" << default_gain_mode; - } - - if ((gain_mode_rx2_ != "manual") && (gain_mode_rx2_ != "slow_attack") && (gain_mode_rx2_ != "fast_attack") && (gain_mode_rx2_ != "hybrid")) - { - std::cout << "Configuration parameter gain_mode_rx2 should take one of these values:\n"; - std::cout << " manual, slow_attack, fast_attack, hybrid\n"; - std::cout << "Error: provided value gain_mode_rx2=" << gain_mode_rx2_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value gain_mode_rx2=" << default_gain_mode << '\n'; - gain_mode_rx2_ = default_gain_mode; - LOG(WARNING) << "Invalid configuration value for gain_mode_rx2 parameter. Set to gain_mode_rx2=" << default_gain_mode; - } - - if (gain_mode_rx1_ == "manual") - { - if (rf_gain_rx1_ > 73.0 || rf_gain_rx1_ < -1.0) - { - std::cout << "Configuration parameter rf_gain_rx1 should take values between -1.0 and 73 dB\n"; - std::cout << "Error: provided value rf_gain_rx1=" << rf_gain_rx1_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value rf_gain_rx1=" << default_manual_gain_rx1 << '\n'; - rf_gain_rx1_ = default_manual_gain_rx1; - LOG(WARNING) << "Invalid configuration value for rf_gain_rx1 parameter. Set to rf_gain_rx1=" << default_manual_gain_rx1; - } - } - - if (gain_mode_rx2_ == "manual") - { - if (rf_gain_rx2_ > 73.0 || rf_gain_rx2_ < -1.0) - { - std::cout << "Configuration parameter rf_gain_rx2 should take values between -1.0 and 73 dB\n"; - std::cout << "Error: provided value rf_gain_rx2=" << rf_gain_rx2_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value rf_gain_rx2=" << default_manual_gain_rx2 << '\n'; - rf_gain_rx2_ = default_manual_gain_rx2; - LOG(WARNING) << "Invalid configuration value for rf_gain_rx2 parameter. Set to rf_gain_rx2=" << default_manual_gain_rx2; - } - } - - if ((filter_source_ != "Off") && (filter_source_ != "Auto") && (filter_source_ != "File") && (filter_source_ != "Design")) - { - std::cout << "Configuration parameter filter_source should take one of these values:\n"; - std::cout << " Off: Disable filter\n"; - std::cout << " Auto: Use auto-generated filters\n"; - std::cout << " File: User-provided filter in filter_filename parameter\n"; - std::cout << " Design: Create filter from Fpass, Fstop, sampling_frequency and bandwidth parameters\n"; - std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value filter_source=Off\n"; - filter_source_ = std::string("Off"); - LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off"; - } - - if (bandwidth_ < 200000 || bandwidth_ > 56000000) - { - std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz\n"; - std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value bandwidth=" << default_bandwidth << '\n'; - bandwidth_ = default_bandwidth; - LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=" << default_bandwidth; - } - - std::cout << "LO frequency : " << freq0_ << " Hz\n"; - try - { - config_ad9361_rx_local(bandwidth_, - sample_rate_, - freq0_, - freq1_, - rf_port_select_, - rx1_enable_, - rx2_enable_, - gain_mode_rx1_, - gain_mode_rx2_, - rf_gain_rx1_, - rf_gain_rx2_, - quadrature_, - rf_dc_, - bb_dc_, - filter_source_, - filter_filename_, - Fpass_, - Fstop_); - } - catch (const std::runtime_error &e) - { - std::cerr << "Exception cached when configuring the RX chain: " << e.what() << '\n'; - return; - } - // LOCAL OSCILLATOR DDS GENERATOR FOR DUAL FREQUENCY OPERATION - if (enable_dds_lo_ == true) - { - if (tx_bandwidth_ < static_cast(std::floor(static_cast(freq_dds_tx_hz_) * 1.1)) || (tx_bandwidth_ < 200000) || (tx_bandwidth_ > 1000000)) - { - std::cout << "Configuration parameter tx_bandwidth value should be between " << std::max(static_cast(freq_dds_tx_hz_) * 1.1, 200000.0) << " and 1000000 Hz\n"; - std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value tx_bandwidth=500000\n"; - tx_bandwidth_ = 500000; - LOG(WARNING) << "Invalid configuration value for tx_bandwidth parameter. Set to tx_bandwidth=500000"; - } - if (tx_attenuation_db_ > 0.0 || tx_attenuation_db_ < -89.75) - { - std::cout << "Configuration parameter tx_attenuation_db should take values between 0.0 and -89.95 in 0.25 dB steps\n"; - std::cout << "Error: provided value tx_attenuation_db=" << tx_attenuation_db_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value tx_attenuation_db=" << default_tx_attenuation_db << '\n'; - tx_attenuation_db_ = default_tx_attenuation_db; - LOG(WARNING) << "Invalid configuration value for tx_attenuation_db parameter. Set to tx_attenuation_db=" << default_tx_attenuation_db; - } - try - { - config_ad9361_lo_local(tx_bandwidth_, - sample_rate_, - freq_rf_tx_hz_, - tx_attenuation_db_, - freq_dds_tx_hz_, - scale_dds_dbfs_, - phase_dds_deg_); - } - catch (const std::runtime_error &e) - { - std::cerr << "Exception cached when configuring the TX carrier: " << e.what() << '\n'; - return; - } - } - - // when the receiver is working in real-time mode via AD9361 perform buffer overflow checking, - // and if dump is enabled perform buffer monitoring - enable_ovf_check_buffer_monitor_active_ = true; - - std::string device_io_name_buffer_monitor; - - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - - // find the uio device file corresponding to the buffer monitor - if (find_uio_dev_file_name(device_io_name_buffer_monitor, buffer_monitor_device_name, 0) < 0) - { - std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << buffer_monitor_device_name << '\n'; - return; - } - - buffer_monitor_fpga = std::make_shared(device_io_name_buffer_monitor, num_freq_bands, dump_, dump_filename); - thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); }); - } - - // dynamic bits selection - if (enable_dynamic_bit_selection_) - { - dynamic_bit_selection_fpga = std::make_shared(enable_rx1_band, enable_rx2_band); - thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); - } - - if (in_stream_ > 0) - { - LOG(ERROR) << "A signal source does not have an input stream"; - } - if (out_stream_ > 1) - { - LOG(ERROR) << "This implementation only supports one output stream"; - } -} - - -Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource() -{ - /* cleanup and exit */ - if (switch_position_ == 0) // read samples from a file via DMA - { - std::unique_lock lock(dma_mutex); - enable_DMA_ = false; // disable the DMA - lock.unlock(); - if (thread_file_to_dma.joinable()) - { - thread_file_to_dma.join(); - } - } - - if (switch_position_ == 2) // Real-time via AD9361 - { - if (rf_shutdown_) - { - std::cout << "* AD9361 Disabling RX streaming channels\n"; - if (!disable_ad9361_rx_local()) - { - LOG(WARNING) << "Problem shutting down the AD9361 RX channels"; - } - if (enable_dds_lo_) - { - try - { - ad9361_disable_lo_local(); - } - catch (const std::exception &e) - { - LOG(WARNING) << "Problem shutting down the AD9361 TX stream: " << e.what(); - } - } - } - - // disable buffer overflow checking and buffer monitoring - std::unique_lock lock(buffer_monitor_mutex); - enable_ovf_check_buffer_monitor_active_ = false; - lock.unlock(); - - if (thread_buffer_monitor.joinable()) - { - thread_buffer_monitor.join(); - } - } - - std::unique_lock lock(dynamic_bit_selection_mutex); - bool bit_selection_enabled = enable_dynamic_bit_selection_; - lock.unlock(); - - if (bit_selection_enabled == true) - { - std::unique_lock lock(dynamic_bit_selection_mutex); - enable_dynamic_bit_selection_ = false; - lock.unlock(); - - if (thread_dynamic_bit_selection.joinable()) - { - thread_dynamic_bit_selection.join(); - } - } -} - - -void Ad9361FpgaSignalSource::start() -{ - thread_file_to_dma = std::thread([&] { run_DMA_process(filename0_, filename1_, samples_to_skip_, item_size_, samples_, repeat_, dma_buff_offset_pos_, queue_); }); -} - - -void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, const std::string &filename1_, uint64_t &samples_to_skip, size_t &item_size, int64_t &samples, bool &repeat, uint32_t &dma_buff_offset_pos, Concurrent_Queue *queue) -{ - std::ifstream infile1; - infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit); - - - // FPGA DMA control - dma_fpga = std::make_shared(); - - // open the files - try - { - infile1.open(filename0_, std::ios::binary); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception opening file " << filename0_ << '\n'; - // stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); - return; - } - - std::ifstream infile2; - if (!filename1_.empty()) - { - infile2.exceptions(std::ifstream::failbit | std::ifstream::badbit); - try - { - infile2.open(filename1_, std::ios::binary); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception opening file " << filename1_ << '\n'; - // stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); - return; - } - } - - // skip the initial samples if needed - uint64_t bytes_to_skeep = samples_to_skip * item_size; - try - { - infile1.ignore(bytes_to_skeep); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception skipping initial samples file " << filename0_ << '\n'; - // stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); - return; - } - - if (!filename1_.empty()) - { - try - { - infile2.ignore(bytes_to_skeep); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception skipping initial samples file " << filename1_ << '\n'; - // stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); - return; - } - } - - // rx signal vectors - std::vector input_samples(sample_block_size * 2); // complex samples - // pointer to DMA buffer - int8_t *dma_buffer; - int nread_elements = 0; // num bytes read from the file corresponding to frequency band 1 - bool run_DMA = true; - - // Open DMA device - if (dma_fpga->DMA_open()) - { - std::cerr << "Cannot open loop device\n"; - // stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); - return; - } - dma_buffer = dma_fpga->get_buffer_address(); - - // if only one frequency band is used then clear the samples corresponding to the unused frequency band - uint32_t dma_index = 0; - if (num_input_files_ == 1) - { - // if only one file is enabled then clear the samples corresponding to the frequency band that is not used. - for (int index0 = 0; index0 < (nread_elements); index0 += 2) - { - dma_buffer[dma_index + (2 - dma_buff_offset_pos)] = 0; - dma_buffer[dma_index + 1 + (2 - dma_buff_offset_pos)] = 0; - dma_index += 4; - } - } - - uint64_t nbytes_remaining = samples * item_size; - uint32_t read_buffer_size = sample_block_size * 2; // complex samples - - // run the DMA - while (run_DMA) - { - dma_index = 0; - if (nbytes_remaining < read_buffer_size) - { - read_buffer_size = nbytes_remaining; - } - nbytes_remaining = nbytes_remaining - read_buffer_size; - - // read filename 0 - try - { - infile1.read(reinterpret_cast(input_samples.data()), read_buffer_size); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception reading file " << filename0_ << '\n'; - break; - } - if (infile1) - { - nread_elements = read_buffer_size; - } - else - { - // FLAG AS ERROR !! IT SHOULD NEVER HAPPEN - nread_elements = infile1.gcount(); - } - - for (int index0 = 0; index0 < (nread_elements); index0 += 2) - { - // dma_buff_offset_pos is 1 for the L1 band and 0 for the other bands - dma_buffer[dma_index + dma_buff_offset_pos] = input_samples[index0]; - dma_buffer[dma_index + 1 + dma_buff_offset_pos] = input_samples[index0 + 1]; - dma_index += 4; - } - - // read filename 1 (if enabled) - if (num_input_files_ > 1) - { - dma_index = 0; - try - { - infile2.read(reinterpret_cast(input_samples.data()), read_buffer_size); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception reading file " << filename1_ << '\n'; - break; - } - if (infile2) - { - nread_elements = read_buffer_size; - } - else - { - // FLAG AS ERROR !! IT SHOULD NEVER HAPPEN - nread_elements = infile2.gcount(); - } - - for (int index0 = 0; index0 < (nread_elements); index0 += 2) - { - // filename2 is never the L1 band - dma_buffer[dma_index] = input_samples[index0]; - dma_buffer[dma_index + 1] = input_samples[index0 + 1]; - dma_index += 4; - } - } - - if (nread_elements > 0) - { - if (dma_fpga->DMA_write(nread_elements * 2)) - { - std::cerr << "Error: DMA could not send all the required samples\n"; - break; - } - // Throttle the DMA - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } - - if (nbytes_remaining == 0) - { - if (repeat) - { - // read the file again - nbytes_remaining = samples * item_size; - read_buffer_size = sample_block_size * 2; - try - { - infile1.seekg(0); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception resetting the position of the next byte to be extracted to zero " << filename0_ << '\n'; - break; - } - - // skip the initial samples if needed - uint64_t bytes_to_skeep = samples_to_skip * item_size; - try - { - infile1.ignore(bytes_to_skeep); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception skipping initial samples file " << filename0_ << '\n'; - break; - } - - if (!filename1_.empty()) - { - try - { - infile2.seekg(0); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception setting the position of the next byte to be extracted to zero " << filename1_ << '\n'; - break; - } - - try - { - infile2.ignore(bytes_to_skeep); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception skipping initial samples file " << filename1_ << '\n'; - break; - } - } - } - else - { - // the input file is completely processed. Stop the receiver. - run_DMA = false; - } - } - std::unique_lock lock(dma_mutex); - if (enable_DMA_ == false) - { - run_DMA = false; - } - lock.unlock(); - } - - if (dma_fpga->DMA_close()) - { - std::cerr << "Error closing loop device " << '\n'; - } - try - { - infile1.close(); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception closing file " << filename0_ << '\n'; - } - - if (num_input_files_ > 1) - { - try - { - infile2.close(); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception closing file " << filename1_ << '\n'; - } - } - - // Stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); -} - - -void Ad9361FpgaSignalSource::run_dynamic_bit_selection_process() -{ - bool dynamic_bit_selection_active = true; - - while (dynamic_bit_selection_active) - { - // setting the bit selection to the top bits - dynamic_bit_selection_fpga->bit_selection(); - std::this_thread::sleep_for(std::chrono::milliseconds(Gain_control_period_ms)); - std::unique_lock lock(dynamic_bit_selection_mutex); - if (enable_dynamic_bit_selection_ == false) - { - dynamic_bit_selection_active = false; - } - lock.unlock(); - } -} - - -void Ad9361FpgaSignalSource::run_buffer_monitor_process() -{ - bool enable_ovf_check_buffer_monitor_active = true; - - std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitoring_initial_delay_ms)); - - while (enable_ovf_check_buffer_monitor_active) - { - buffer_monitor_fpga->check_buffer_overflow_and_monitor_buffer_status(); - std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitor_period_ms)); - std::unique_lock lock(buffer_monitor_mutex); - if (enable_ovf_check_buffer_monitor_active_ == false) - { - enable_ovf_check_buffer_monitor_active = false; - } - lock.unlock(); - } -} - - -void Ad9361FpgaSignalSource::connect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - DLOG(INFO) << "AD9361 FPGA source nothing to connect"; -} - - -void Ad9361FpgaSignalSource::disconnect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - DLOG(INFO) << "AD9361 FPGA source nothing to disconnect"; -} - - -gr::basic_block_sptr Ad9361FpgaSignalSource::get_left_block() -{ - LOG(WARNING) << "Trying to get signal source left block."; - return {}; -} - - -gr::basic_block_sptr Ad9361FpgaSignalSource::get_right_block() -{ - return {}; -} diff --git a/src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.cc b/src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.cc new file mode 100644 index 000000000..9d29e2de2 --- /dev/null +++ b/src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.cc @@ -0,0 +1,398 @@ +/*! + * \file adrv9361_z7035_signal_source_fpga.cc + * \brief signal source for the Analog Devices ADRV9361-Z7035 evaluation board + * directly connected to the FPGA accelerators. + * This source implements only the AD9361 control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * Please use the fmcomms2 source if conventional SDR acquisition and tracking + * is selected in the configuration file. + * \authors
    + *
  • Javier Arribas, jarribas(at)cttc.es + *
  • Marc Majoral, mmajoral(at)cttc.es + *
+ * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "adrv9361_z7035_signal_source_fpga.h" +#include "GPS_L1_CA.h" +#include "GPS_L5.h" +#include "ad9361_manager.h" +#include "configuration_interface.h" +#include "gnss_sdr_flags.h" +#include "gnss_sdr_string_literals.h" +#include // for std::max +#include // for std::chrono +#include // for std::floor +#include // for std::exception +#include // for std::cout + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#endif + +using namespace std::string_literals; + +Adrv9361z7035SignalSourceFPGA::Adrv9361z7035SignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, unsigned int out_stream, + Concurrent_Queue *queue __attribute__((unused))) + : SignalSourceBase(configuration, role, "ADRV9361_Z7035_Signal_Source_FPGA"s), + gain_mode_rx1_(configuration->property(role + ".gain_mode_rx1", default_gain_mode)), + gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)), + rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)), + filter_filename_(configuration->property(role + ".filter_filename", filter_file_)), + rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)), + rf_gain_rx2_(configuration->property(role + ".gain_rx2", default_manual_gain_rx2)), + scale_dds_dbfs_(configuration->property(role + ".scale_dds_dbfs", -3.0)), + phase_dds_deg_(configuration->property(role + ".phase_dds_deg", 0.0)), + tx_attenuation_db_(configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db)), + freq0_(configuration->property(role + ".freq", 0)), + freq1_(configuration->property(role + ".freq1", static_cast(GPS_L5_FREQ_HZ))), + sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)), + bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)), + freq_dds_tx_hz_(configuration->property(role + ".freq_dds_tx_hz", uint64_t(10000))), + freq_rf_tx_hz_(configuration->property(role + ".freq_rf_tx_hz", static_cast(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_))), + tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast(500000))), + Fpass_(configuration->property(role + ".Fpass", static_cast(0.0))), + Fstop_(configuration->property(role + ".Fstop", static_cast(0.0))), + in_stream_(in_stream), + out_stream_(out_stream), + item_size_(sizeof(int8_t)), + enable_dds_lo_(configuration->property(role + ".enable_dds_lo", false)), + filter_auto_(configuration->property(role + ".filter_auto", false)), + quadrature_(configuration->property(role + ".quadrature", true)), + rf_dc_(configuration->property(role + ".rf_dc", true)), + bb_dc_(configuration->property(role + ".bb_dc", true)), + rx1_enable_(configuration->property(role + ".rx1_enable", true)), + rx2_enable_(configuration->property(role + ".rx2_enable", true)), + enable_dynamic_bit_selection_(configuration->property(role + ".enable_dynamic_bit_selection", true)), + enable_ovf_check_buffer_monitor_active_(true), + dump_(configuration->property(role + ".dump", false)), +#if USE_GLOG_AND_GFLAGS + rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)) +#else + rf_shutdown_(configuration->property(role + ".rf_shutdown", absl::GetFlag(FLAGS_rf_shutdown))) +#endif +{ + const bool enable_rx1_band((configuration->property("Channels_1C.count", 0) > 0) || + (configuration->property("Channels_1B.count", 0) > 0)); + const bool enable_rx2_band((configuration->property("Channels_L2.count", 0) > 0) || + (configuration->property("Channels_L5.count", 0) > 0) || + (configuration->property("Channels_5X.count", 0) > 0)); + + const uint32_t num_freq_bands = ((enable_rx1_band == true) and (enable_rx2_band == true)) ? 2 : 1; + if (freq0_ == 0) + { + // use ".freq0" + freq0_ = configuration->property(role + ".freq0", static_cast(GPS_L1_FREQ_HZ)); + } + + if (filter_auto_) + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Auto")); + } + else + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); + } + + switch_fpga = std::make_shared(); + switch_fpga->set_switch_position(switch_to_real_time_mode); + + std::cout << "Sample rate: " << sample_rate_ << " Sps\n"; + + // some basic checks + if ((rf_port_select_ != "A_BALANCED") && (rf_port_select_ != "B_BALANCED") && (rf_port_select_ != "A_N") && (rf_port_select_ != "B_N") && (rf_port_select_ != "B_P") && (rf_port_select_ != "C_N") && (rf_port_select_ != "C_P") && (rf_port_select_ != "TX_MONITOR1") && (rf_port_select_ != "TX_MONITOR2") && (rf_port_select_ != "TX_MONITOR1_2")) + { + std::cout << "Configuration parameter rf_port_select should take one of these values:\n"; + std::cout << " A_BALANCED, B_BALANCED, A_N, B_N, B_P, C_N, C_P, TX_MONITOR1, TX_MONITOR2, TX_MONITOR1_2\n"; + std::cout << "Error: provided value rf_port_select=" << rf_port_select_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_port_select=" << default_rf_port_select << '\n'; + rf_port_select_ = default_rf_port_select; + LOG(WARNING) << "Invalid configuration value for rf_port_select parameter. Set to rf_port_select=" << default_rf_port_select; + } + + if ((gain_mode_rx1_ != "manual") && (gain_mode_rx1_ != "slow_attack") && (gain_mode_rx1_ != "fast_attack") && (gain_mode_rx1_ != "hybrid")) + { + std::cout << "Configuration parameter gain_mode_rx1 should take one of these values:\n"; + std::cout << " manual, slow_attack, fast_attack, hybrid\n"; + std::cout << "Error: provided value gain_mode_rx1=" << gain_mode_rx1_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value gain_mode_rx1=" << default_gain_mode << '\n'; + gain_mode_rx1_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx1 parameter. Set to gain_mode_rx1=" << default_gain_mode; + } + + if ((gain_mode_rx2_ != "manual") && (gain_mode_rx2_ != "slow_attack") && (gain_mode_rx2_ != "fast_attack") && (gain_mode_rx2_ != "hybrid")) + { + std::cout << "Configuration parameter gain_mode_rx2 should take one of these values:\n"; + std::cout << " manual, slow_attack, fast_attack, hybrid\n"; + std::cout << "Error: provided value gain_mode_rx2=" << gain_mode_rx2_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value gain_mode_rx2=" << default_gain_mode << '\n'; + gain_mode_rx2_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx2 parameter. Set to gain_mode_rx2=" << default_gain_mode; + } + + if (gain_mode_rx1_ == "manual") + { + if (rf_gain_rx1_ > 73.0 || rf_gain_rx1_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx1 should take values between -1.0 and 73 dB\n"; + std::cout << "Error: provided value rf_gain_rx1=" << rf_gain_rx1_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_gain_rx1=" << default_manual_gain_rx1 << '\n'; + rf_gain_rx1_ = default_manual_gain_rx1; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx1 parameter. Set to rf_gain_rx1=" << default_manual_gain_rx1; + } + } + + if (gain_mode_rx2_ == "manual") + { + if (rf_gain_rx2_ > 73.0 || rf_gain_rx2_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx2 should take values between -1.0 and 73 dB\n"; + std::cout << "Error: provided value rf_gain_rx2=" << rf_gain_rx2_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_gain_rx2=" << default_manual_gain_rx2 << '\n'; + rf_gain_rx2_ = default_manual_gain_rx2; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx2 parameter. Set to rf_gain_rx2=" << default_manual_gain_rx2; + } + } + + if ((filter_source_ != "Off") && (filter_source_ != "Auto") && (filter_source_ != "File") && (filter_source_ != "Design")) + { + std::cout << "Configuration parameter filter_source should take one of these values:\n"; + std::cout << " Off: Disable filter\n"; + std::cout << " Auto: Use auto-generated filters\n"; + std::cout << " File: User-provided filter in filter_filename parameter\n"; + std::cout << " Design: Create filter from Fpass, Fstop, sampling_frequency and bandwidth parameters\n"; + std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value filter_source=Off\n"; + filter_source_ = std::string("Off"); + LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off"; + } + + if (bandwidth_ < 200000 || bandwidth_ > 56000000) + { + std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz\n"; + std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value bandwidth=" << default_bandwidth << '\n'; + bandwidth_ = default_bandwidth; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=" << default_bandwidth; + } + + std::cout << "LO frequency : " << freq0_ << " Hz\n"; + try + { + config_ad9361_rx_local(bandwidth_, + sample_rate_, + freq0_, + freq1_, + rf_port_select_, + rx1_enable_, + rx2_enable_, + gain_mode_rx1_, + gain_mode_rx2_, + rf_gain_rx1_, + rf_gain_rx2_, + quadrature_, + rf_dc_, + bb_dc_, + filter_source_, + filter_filename_, + Fpass_, + Fstop_); + } + catch (const std::runtime_error &e) + { + std::cerr << "Exception cached when configuring the RX chain: " << e.what() << '\n'; + return; + } + // LOCAL OSCILLATOR DDS GENERATOR FOR DUAL FREQUENCY OPERATION + if (enable_dds_lo_ == true) + { + if (tx_bandwidth_ < static_cast(std::floor(static_cast(freq_dds_tx_hz_) * 1.1)) || (tx_bandwidth_ < 200000) || (tx_bandwidth_ > 1000000)) + { + std::cout << "Configuration parameter tx_bandwidth value should be between " << std::max(static_cast(freq_dds_tx_hz_) * 1.1, 200000.0) << " and 1000000 Hz\n"; + std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value tx_bandwidth=500000\n"; + tx_bandwidth_ = 500000; + LOG(WARNING) << "Invalid configuration value for tx_bandwidth parameter. Set to tx_bandwidth=500000"; + } + if (tx_attenuation_db_ > 0.0 || tx_attenuation_db_ < -89.75) + { + std::cout << "Configuration parameter tx_attenuation_db should take values between 0.0 and -89.95 in 0.25 dB steps\n"; + std::cout << "Error: provided value tx_attenuation_db=" << tx_attenuation_db_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value tx_attenuation_db=" << default_tx_attenuation_db << '\n'; + tx_attenuation_db_ = default_tx_attenuation_db; + LOG(WARNING) << "Invalid configuration value for tx_attenuation_db parameter. Set to tx_attenuation_db=" << default_tx_attenuation_db; + } + try + { + config_ad9361_lo_local(tx_bandwidth_, + sample_rate_, + freq_rf_tx_hz_, + tx_attenuation_db_, + freq_dds_tx_hz_, + scale_dds_dbfs_, + phase_dds_deg_); + } + catch (const std::runtime_error &e) + { + std::cerr << "Exception cached when configuring the TX carrier: " << e.what() << '\n'; + return; + } + } + + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + + buffer_monitor_fpga = std::make_shared(num_freq_bands, dump_, dump_filename); + thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); }); + + + // dynamic bits selection + if (enable_dynamic_bit_selection_) + { + dynamic_bit_selection_fpga = std::make_shared(enable_rx1_band, enable_rx2_band); + thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); + } + + if (in_stream_ > 0) + { + LOG(ERROR) << "A signal source does not have an input stream"; + } + if (out_stream_ > 1) + { + LOG(ERROR) << "This implementation only supports one output stream"; + } +} + + +Adrv9361z7035SignalSourceFPGA::~Adrv9361z7035SignalSourceFPGA() +{ + /* cleanup and exit */ + + if (rf_shutdown_) + { + std::cout << "* AD9361 Disabling RX streaming channels\n"; + if (!disable_ad9361_rx_local()) + { + LOG(WARNING) << "Problem shutting down the AD9361 RX channels"; + } + if (enable_dds_lo_) + { + try + { + ad9361_disable_lo_local(); + } + catch (const std::exception &e) + { + LOG(WARNING) << "Problem shutting down the AD9361 TX stream: " << e.what(); + } + } + } + + // disable buffer overflow checking and buffer monitoring + std::unique_lock lock_buffer_monitor(buffer_monitor_mutex); + enable_ovf_check_buffer_monitor_active_ = false; + lock_buffer_monitor.unlock(); + + if (thread_buffer_monitor.joinable()) + { + thread_buffer_monitor.join(); + } + + std::unique_lock lock_dyn_bit_sel(dynamic_bit_selection_mutex); + bool bit_selection_enabled = enable_dynamic_bit_selection_; + lock_dyn_bit_sel.unlock(); + + if (bit_selection_enabled == true) + { + std::unique_lock lock(dynamic_bit_selection_mutex); + enable_dynamic_bit_selection_ = false; + lock.unlock(); + + if (thread_dynamic_bit_selection.joinable()) + { + thread_dynamic_bit_selection.join(); + } + } +} + + +void Adrv9361z7035SignalSourceFPGA::run_dynamic_bit_selection_process() +{ + bool dynamic_bit_selection_active = true; + + while (dynamic_bit_selection_active) + { + // setting the bit selection to the top bits + dynamic_bit_selection_fpga->bit_selection(); + std::this_thread::sleep_for(std::chrono::milliseconds(Gain_control_period_ms)); + std::unique_lock lock(dynamic_bit_selection_mutex); + if (enable_dynamic_bit_selection_ == false) + { + dynamic_bit_selection_active = false; + } + lock.unlock(); + } +} + + +void Adrv9361z7035SignalSourceFPGA::run_buffer_monitor_process() +{ + bool enable_ovf_check_buffer_monitor_active = true; + + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitoring_initial_delay_ms)); + + while (enable_ovf_check_buffer_monitor_active) + { + buffer_monitor_fpga->check_buffer_overflow_and_monitor_buffer_status(); + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitor_period_ms)); + std::unique_lock lock(buffer_monitor_mutex); + if (enable_ovf_check_buffer_monitor_active_ == false) + { + enable_ovf_check_buffer_monitor_active = false; + } + lock.unlock(); + } +} + + +void Adrv9361z7035SignalSourceFPGA::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to connect"; +} + + +void Adrv9361z7035SignalSourceFPGA::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to disconnect"; +} + + +gr::basic_block_sptr Adrv9361z7035SignalSourceFPGA::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + return {}; +} + + +gr::basic_block_sptr Adrv9361z7035SignalSourceFPGA::get_right_block() +{ + return {}; +} diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.h similarity index 70% rename from src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h rename to src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.h index bedd25ad5..5e7e8b7e4 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h +++ b/src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.h @@ -1,7 +1,7 @@ /*! - * \file ad9361_fpga_signal_source.h - * \brief signal source for Analog Devices front-end AD9361 connected directly - * to FPGA accelerators. + * \file adrv9361_z7035_signal_source_fpga.h + * \brief signal source for the Analog Devices ADRV9361-Z7035 evaluation board + * directly connected to the FPGA accelerators. * This source implements only the AD9361 control. It is NOT compatible with * conventional SDR acquisition and tracking blocks. * Please use the fmcomms2 source if conventional SDR acquisition and tracking @@ -12,14 +12,14 @@ * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * This file is part of GNSS-SDR. * - * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- */ -#ifndef GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H -#define GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H +#ifndef GNSS_SDR_ADRV9361_Z7035_SIGNAL_SOURCE_FPGA_H +#define GNSS_SDR_ADRV9361_Z7035_SIGNAL_SOURCE_FPGA_H #include "concurrent_queue.h" #include "fpga_buffer_monitor.h" @@ -44,16 +44,14 @@ class ConfigurationInterface; -class Ad9361FpgaSignalSource : public SignalSourceBase +class Adrv9361z7035SignalSourceFPGA : public SignalSourceBase { public: - Ad9361FpgaSignalSource(const ConfigurationInterface *configuration, + Adrv9361z7035SignalSourceFPGA(const ConfigurationInterface *configuration, const std::string &role, unsigned int in_stream, unsigned int out_stream, Concurrent_Queue *queue); - ~Ad9361FpgaSignalSource(); - - void start() override; + ~Adrv9361z7035SignalSourceFPGA(); inline size_t item_size() override { @@ -66,13 +64,9 @@ public: gr::basic_block_sptr get_right_block() override; private: - const std::string switch_device_name = std::string("AXIS_Switch_v1_0_0"); // Switch UIO device name - const std::string dyn_bit_sel_device_name = std::string("dynamic_bits_selector"); // Switch dhnamic bit selector device name - const std::string buffer_monitor_device_name = std::string("buffer_monitor"); // buffer monitor device name const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat"); const std::string default_rf_port_select = std::string("A_BALANCED"); const std::string default_gain_mode = std::string("slow_attack"); - const std::string empty_string; const double default_tx_attenuation_db = -10.0; const double default_manual_gain_rx1 = 64.0; const double default_manual_gain_rx2 = 64.0; @@ -86,42 +80,27 @@ private: const uint32_t buffer_monitoring_initial_delay_ms = 2000; // sample block size when running in post-processing mode const int sample_block_size = 16384; - - void run_DMA_process(const std::string &filename0, - const std::string &filename1, - uint64_t &samples_to_skip, - size_t &item_size, - int64_t &samples, - bool &repeat, - uint32_t &dma_buff_offset_pos, - Concurrent_Queue *queue); + const int32_t switch_to_real_time_mode = 2; void run_dynamic_bit_selection_process(); void run_buffer_monitor_process(); - std::thread thread_file_to_dma; std::thread thread_dynamic_bit_selection; std::thread thread_buffer_monitor; std::shared_ptr switch_fpga; std::shared_ptr dynamic_bit_selection_fpga; std::shared_ptr buffer_monitor_fpga; - std::shared_ptr dma_fpga; - std::mutex dma_mutex; std::mutex dynamic_bit_selection_mutex; std::mutex buffer_monitor_mutex; - Concurrent_Queue *queue_; - std::string gain_mode_rx1_; std::string gain_mode_rx2_; std::string rf_port_select_; std::string filter_file_; std::string filter_source_; std::string filter_filename_; - std::string filename0_; - std::string filename1_; double rf_gain_rx1_; double rf_gain_rx2_; @@ -133,19 +112,14 @@ private: uint64_t freq1_; // frequency of local oscillator for ADRV9361-B (if present) uint64_t sample_rate_; uint64_t bandwidth_; - uint64_t samples_to_skip_; - int64_t samples_; uint64_t freq_dds_tx_hz_; uint64_t freq_rf_tx_hz_; uint64_t tx_bandwidth_; float Fpass_; float Fstop_; - uint32_t num_input_files_; - uint32_t dma_buff_offset_pos_; uint32_t in_stream_; uint32_t out_stream_; - int32_t switch_position_; size_t item_size_; @@ -156,15 +130,13 @@ private: bool bb_dc_; bool rx1_enable_; bool rx2_enable_; - bool enable_DMA_; bool enable_dynamic_bit_selection_; bool enable_ovf_check_buffer_monitor_active_; bool dump_; bool rf_shutdown_; - bool repeat_; }; /** \} */ /** \} */ -#endif // GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H +#endif // GNSS_SDR_ADRV9361_Z7035_SIGNAL_SOURCE_FPGA_H diff --git a/src/algorithms/signal_source/adapters/dma_signal_source_fpga.cc b/src/algorithms/signal_source/adapters/dma_signal_source_fpga.cc new file mode 100644 index 000000000..6d4f91b03 --- /dev/null +++ b/src/algorithms/signal_source/adapters/dma_signal_source_fpga.cc @@ -0,0 +1,581 @@ +/*! + * \file dma_signal_source_fpga.cc + * \brief signal source for a DMA connected directly to FPGA accelerators. + * This source implements only the DMA control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * \author Marc Majoral, mmajoral(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "dma_signal_source_fpga.h" +#include "command_event.h" +#include "configuration_interface.h" +#include "gnss_sdr_flags.h" +#include "gnss_sdr_string_literals.h" +#include // for std::min +#include // for std::chrono +#include // for open, O_WRONLY +#include // for std::ifstream +#include // for std::setprecision +#include // for std::cout +#include // fr std::vector + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#endif + +using namespace std::string_literals; + +DMASignalSourceFPGA::DMASignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, unsigned int out_stream, + Concurrent_Queue *queue __attribute__((unused))) + : SignalSourceBase(configuration, role, "DMA_Signal_Source_FPGA"s), + queue_(queue), + filename0_(configuration->property(role + ".filename", empty_string)), + sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)), + samples_to_skip_(0), + samples_(configuration->property(role + ".samples", static_cast(0))), + num_input_files_(1), + dma_buff_offset_pos_(0), + in_stream_(in_stream), + out_stream_(out_stream), + item_size_(sizeof(int8_t)), + enable_DMA_(false), + enable_dynamic_bit_selection_(configuration->property(role + ".enable_dynamic_bit_selection", true)), + repeat_(configuration->property(role + ".repeat", false)) +{ + const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", 0.0); + const size_t header_size = configuration->property(role + ".header_size", 0); + + const bool enable_rx1_band((configuration->property("Channels_1C.count", 0) > 0) || + (configuration->property("Channels_1B.count", 0) > 0)); + const bool enable_rx2_band((configuration->property("Channels_L2.count", 0) > 0) || + (configuration->property("Channels_L5.count", 0) > 0) || + (configuration->property("Channels_5X.count", 0) > 0)); + +#if USE_GLOG_AND_GFLAGS + // override value with commandline flag, if present + if (FLAGS_signal_source != "-") + { + filename0_ = FLAGS_signal_source; + } + if (FLAGS_s != "-") + { + filename0_ = FLAGS_s; + } +#else + if (absl::GetFlag(FLAGS_signal_source) != "-") + { + filename0_ = absl::GetFlag(FLAGS_signal_source); + } + if (absl::GetFlag(FLAGS_s) != "-") + { + filename0_ = absl::GetFlag(FLAGS_s); + } +#endif + if (filename0_.empty()) + { + num_input_files_ = 2; + filename0_ = configuration->property(role + ".filename0", empty_string); + filename1_ = configuration->property(role + ".filename1", empty_string); + } + // if only one input file is specified in the configuration file then: + // if there is at least one channel assigned to frequency band 1 then the DMA transfers the samples to the L1 frequency band channels + // otherwise the DMA transfers the samples to the L2/L5 frequency band channels + // if more than one input file are specified then the DMA transfer the samples to both the L1 and the L2/L5 frequency channels. + if (filename1_.empty()) + { + if (enable_rx1_band) + { + dma_buff_offset_pos_ = 2; + } + } + else + { + dma_buff_offset_pos_ = 2; + } + + if (seconds_to_skip > 0) + { + samples_to_skip_ = static_cast(seconds_to_skip * sample_rate_) * 2; + } + if (header_size > 0) + { + samples_to_skip_ += header_size; + } + + switch_fpga = std::make_shared(); + switch_fpga->set_switch_position(switch_to_DMA); + + enable_DMA_ = true; + + if (samples_ == 0) // read all file + { + std::ifstream file(filename0_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); + std::ifstream::pos_type size; + + if (file.is_open()) + { + size = file.tellg(); + DLOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size_)); + } + else + { + std::cerr << "SignalSource: Unable to open the samples file " << filename0_.c_str() << '\n'; + return; + } + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(16); + std::cout << "Processing file " << filename0_ << ", which contains " << static_cast(size) << " [bytes]\n"; + std::cout.precision(ss); + + if (size > 0) + { + const uint64_t bytes_to_skip = samples_to_skip_ * item_size_; + const uint64_t bytes_to_process = static_cast(size) - bytes_to_skip; + samples_ = floor(static_cast(bytes_to_process) / static_cast(item_size_) - ceil(0.002 * static_cast(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms + } + + if (!filename1_.empty()) + { + std::ifstream file(filename1_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); + std::ifstream::pos_type size; + + if (file.is_open()) + { + size = file.tellg(); + DLOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size_)); + } + else + { + std::cerr << "SignalSource: Unable to open the samples file " << filename1_.c_str() << '\n'; + return; + } + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(16); + std::cout << "Processing file " << filename1_ << ", which contains " << static_cast(size) << " [bytes]\n"; + std::cout.precision(ss); + + int64_t samples_rx2 = 0; + if (size > 0) + { + const uint64_t bytes_to_skip = samples_to_skip_ * item_size_; + const uint64_t bytes_to_process = static_cast(size) - bytes_to_skip; + samples_rx2 = floor(static_cast(bytes_to_process) / static_cast(item_size_) - ceil(0.002 * static_cast(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms + } + samples_ = std::min(samples_, samples_rx2); + } + } + + CHECK(samples_ > 0) << "File does not contain enough samples to process."; + double signal_duration_s = (static_cast(samples_) * (1 / static_cast(sample_rate_))) / 2.0; + + DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; + std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n"; + + if (filename1_.empty()) + { + DLOG(INFO) << "File source filename " << filename0_; + } + else + { + DLOG(INFO) << "File source filename rx1 " << filename0_; + DLOG(INFO) << "File source filename rx2 " << filename1_; + } + DLOG(INFO) << "Samples " << samples_; + DLOG(INFO) << "Sampling frequency " << sample_rate_; + DLOG(INFO) << "Item type " << std::string("ibyte"); + DLOG(INFO) << "Item size " << item_size_; + DLOG(INFO) << "Repeat " << repeat_; + // } + + // dynamic bits selection + if (enable_dynamic_bit_selection_) + { + dynamic_bit_selection_fpga = std::make_shared(enable_rx1_band, enable_rx2_band); + thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); + } + + if (in_stream_ > 0) + { + LOG(ERROR) << "A signal source does not have an input stream"; + } + if (out_stream_ > 1) + { + LOG(ERROR) << "This implementation only supports one output stream"; + } +} + + +DMASignalSourceFPGA::~DMASignalSourceFPGA() +{ + std::unique_lock lock_DMA(dma_mutex); + enable_DMA_ = false; // disable the DMA + lock_DMA.unlock(); + if (thread_file_to_dma.joinable()) + { + thread_file_to_dma.join(); + } + + std::unique_lock lock_dyn_bit_sel(dynamic_bit_selection_mutex); + bool bit_selection_enabled = enable_dynamic_bit_selection_; + lock_dyn_bit_sel.unlock(); + + if (bit_selection_enabled == true) + { + std::unique_lock lock(dynamic_bit_selection_mutex); + enable_dynamic_bit_selection_ = false; + lock.unlock(); + + if (thread_dynamic_bit_selection.joinable()) + { + thread_dynamic_bit_selection.join(); + } + } +} + + +void DMASignalSourceFPGA::start() +{ + thread_file_to_dma = std::thread([&] { run_DMA_process(filename0_, filename1_, samples_to_skip_, item_size_, samples_, repeat_, dma_buff_offset_pos_, queue_); }); +} + + +void DMASignalSourceFPGA::run_DMA_process(const std::string &filename0_, const std::string &filename1_, uint64_t &samples_to_skip, size_t &item_size, int64_t &samples, bool &repeat, uint32_t &dma_buff_offset_pos, Concurrent_Queue *queue) +{ + std::ifstream infile1; + infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit); + + + // FPGA DMA control + dma_fpga = std::make_shared(); + + // open the files + try + { + infile1.open(filename0_, std::ios::binary); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception opening file " << filename0_ << '\n'; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + + std::ifstream infile2; + if (!filename1_.empty()) + { + infile2.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + infile2.open(filename1_, std::ios::binary); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception opening file " << filename1_ << '\n'; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + } + + // skip the initial samples if needed + uint64_t bytes_to_skeep = samples_to_skip * item_size; + try + { + infile1.ignore(bytes_to_skeep); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception skipping initial samples file " << filename0_ << '\n'; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + + if (!filename1_.empty()) + { + try + { + infile2.ignore(bytes_to_skeep); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception skipping initial samples file " << filename1_ << '\n'; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + } + + // rx signal vectors + std::vector input_samples(sample_block_size * 2); // complex samples + // pointer to DMA buffer + int8_t *dma_buffer; + int nread_elements = 0; // num bytes read from the file corresponding to frequency band 1 + bool run_DMA = true; + + // Open DMA device + if (dma_fpga->DMA_open()) + { + std::cerr << "Cannot open loop device\n"; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + dma_buffer = dma_fpga->get_buffer_address(); + + // if only one frequency band is used then clear the samples corresponding to the unused frequency band + uint32_t dma_index = 0; + if (num_input_files_ == 1) + { + // if only one file is enabled then clear the samples corresponding to the frequency band that is not used. + for (int index0 = 0; index0 < (nread_elements); index0 += 2) + { + dma_buffer[dma_index + (2 - dma_buff_offset_pos)] = 0; + dma_buffer[dma_index + 1 + (2 - dma_buff_offset_pos)] = 0; + dma_index += 4; + } + } + + uint64_t nbytes_remaining = samples * item_size; + uint32_t read_buffer_size = sample_block_size * 2; // complex samples + + // run the DMA + while (run_DMA) + { + dma_index = 0; + if (nbytes_remaining < read_buffer_size) + { + read_buffer_size = nbytes_remaining; + } + nbytes_remaining = nbytes_remaining - read_buffer_size; + + // read filename 0 + try + { + infile1.read(reinterpret_cast(input_samples.data()), read_buffer_size); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception reading file " << filename0_ << '\n'; + break; + } + if (infile1) + { + nread_elements = read_buffer_size; + } + else + { + // FLAG AS ERROR !! IT SHOULD NEVER HAPPEN + nread_elements = infile1.gcount(); + } + + for (int index0 = 0; index0 < (nread_elements); index0 += 2) + { + // dma_buff_offset_pos is 1 for the L1 band and 0 for the other bands + dma_buffer[dma_index + dma_buff_offset_pos] = input_samples[index0]; + dma_buffer[dma_index + 1 + dma_buff_offset_pos] = input_samples[index0 + 1]; + dma_index += 4; + } + + // read filename 1 (if enabled) + if (num_input_files_ > 1) + { + dma_index = 0; + try + { + infile2.read(reinterpret_cast(input_samples.data()), read_buffer_size); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception reading file " << filename1_ << '\n'; + break; + } + if (infile2) + { + nread_elements = read_buffer_size; + } + else + { + // FLAG AS ERROR !! IT SHOULD NEVER HAPPEN + nread_elements = infile2.gcount(); + } + + for (int index0 = 0; index0 < (nread_elements); index0 += 2) + { + // filename2 is never the L1 band + dma_buffer[dma_index] = input_samples[index0]; + dma_buffer[dma_index + 1] = input_samples[index0 + 1]; + dma_index += 4; + } + } + + if (nread_elements > 0) + { + if (dma_fpga->DMA_write(nread_elements * 2)) + { + std::cerr << "Error: DMA could not send all the required samples\n"; + break; + } + // Throttle the DMA + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + if (nbytes_remaining == 0) + { + if (repeat) + { + // read the file again + nbytes_remaining = samples * item_size; + read_buffer_size = sample_block_size * 2; + try + { + infile1.seekg(0); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception resetting the position of the next byte to be extracted to zero " << filename0_ << '\n'; + break; + } + + // skip the initial samples if needed + uint64_t bytes_to_skeep = samples_to_skip * item_size; + try + { + infile1.ignore(bytes_to_skeep); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception skipping initial samples file " << filename0_ << '\n'; + break; + } + + if (!filename1_.empty()) + { + try + { + infile2.seekg(0); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception setting the position of the next byte to be extracted to zero " << filename1_ << '\n'; + break; + } + + try + { + infile2.ignore(bytes_to_skeep); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception skipping initial samples file " << filename1_ << '\n'; + break; + } + } + } + else + { + // the input file is completely processed. Stop the receiver. + run_DMA = false; + } + } + std::unique_lock lock_DMA(dma_mutex); + if (enable_DMA_ == false) + { + run_DMA = false; + } + lock_DMA.unlock(); + } + + if (dma_fpga->DMA_close()) + { + std::cerr << "Error closing loop device " << '\n'; + } + try + { + infile1.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception closing file " << filename0_ << '\n'; + } + + if (num_input_files_ > 1) + { + try + { + infile2.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception closing file " << filename1_ << '\n'; + } + } + + // Stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); +} + + +void DMASignalSourceFPGA::run_dynamic_bit_selection_process() +{ + bool dynamic_bit_selection_active = true; + + while (dynamic_bit_selection_active) + { + // setting the bit selection to the top bits + dynamic_bit_selection_fpga->bit_selection(); + std::this_thread::sleep_for(std::chrono::milliseconds(Gain_control_period_ms)); + std::unique_lock lock_dyn_bit_sel(dynamic_bit_selection_mutex); + if (enable_dynamic_bit_selection_ == false) + { + dynamic_bit_selection_active = false; + } + lock_dyn_bit_sel.unlock(); + } +} + + +void DMASignalSourceFPGA::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to connect"; +} + + +void DMASignalSourceFPGA::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to disconnect"; +} + + +gr::basic_block_sptr DMASignalSourceFPGA::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + return {}; +} + + +gr::basic_block_sptr DMASignalSourceFPGA::get_right_block() +{ + return {}; +} diff --git a/src/algorithms/signal_source/adapters/dma_signal_source_fpga.h b/src/algorithms/signal_source/adapters/dma_signal_source_fpga.h new file mode 100644 index 000000000..efbad3b23 --- /dev/null +++ b/src/algorithms/signal_source/adapters/dma_signal_source_fpga.h @@ -0,0 +1,118 @@ +/*! + * \file dma_signal_source_fpga.h + * \brief signal source for a DMA connected directly to FPGA accelerators. + * This source implements only the DMA control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * \author Marc Majoral, mmajoral(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_DMA_SIGNAL_SOURCE_FPGA_H +#define GNSS_SDR_DMA_SIGNAL_SOURCE_FPGA_H + +#include "concurrent_queue.h" +#include "fpga_dma-proxy.h" +#include "fpga_dynamic_bit_selection.h" +#include "fpga_switch.h" +#include "gnss_block_interface.h" +#include "signal_source_base.h" +#include +#include +#include +#include +#include +#include + + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_adapters + * \{ */ + + +class ConfigurationInterface; + +class DMASignalSourceFPGA : public SignalSourceBase +{ +public: + DMASignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, + unsigned int out_stream, Concurrent_Queue *queue); + + ~DMASignalSourceFPGA(); + + void start() override; + + inline size_t item_size() override + { + return item_size_; + } + + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + +private: + const std::string dyn_bit_sel_device_name = std::string("dynamic_bits_selector"); // Switch dhnamic bit selector device name + const std::string empty_string; + const uint64_t default_bandwidth = 12500000; + // perform dynamic bit selection every 500 ms by default + const uint32_t Gain_control_period_ms = 500; + // sample block size when running in post-processing mode + const int sample_block_size = 16384; + const int32_t switch_to_DMA = 0; + + void run_DMA_process(const std::string &filename0, + const std::string &filename1, + uint64_t &samples_to_skip, + size_t &item_size, + int64_t &samples, + bool &repeat, + uint32_t &dma_buff_offset_pos, + Concurrent_Queue *queue); + + void run_dynamic_bit_selection_process(); + + std::thread thread_file_to_dma; + std::thread thread_dynamic_bit_selection; + + std::shared_ptr switch_fpga; + std::shared_ptr dynamic_bit_selection_fpga; + std::shared_ptr dma_fpga; + + std::mutex dma_mutex; + std::mutex dynamic_bit_selection_mutex; + + Concurrent_Queue *queue_; + + std::string filename0_; + std::string filename1_; + + uint64_t sample_rate_; + uint64_t samples_to_skip_; + int64_t samples_; + uint32_t num_input_files_; + uint32_t dma_buff_offset_pos_; + uint32_t in_stream_; + uint32_t out_stream_; + size_t item_size_; + + bool enable_DMA_; + bool enable_dynamic_bit_selection_; + bool repeat_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_DMA_SIGNAL_SOURCE_FPGA_H diff --git a/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.cc b/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.cc new file mode 100644 index 000000000..d8c5a65c0 --- /dev/null +++ b/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.cc @@ -0,0 +1,347 @@ +/*! + * \file fmcomms5_signal_source_fpga.cc + * \brief signal source for the Analog Devices FMCOMMS5 directly connected + * to the FPGA accelerators. + * This source implements only the AD9361 control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * Please use the fmcomms2 source if conventional SDR acquisition and tracking + * is selected in the configuration file. + * \authors
    + *
  • Javier Arribas, jarribas(at)cttc.es + *
  • Marc Majoral, mmajoral(at)cttc.es + *
+ * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "fmcomms5_signal_source_fpga.h" +#include "GPS_L1_CA.h" +#include "GPS_L5.h" +#include "ad9361_manager.h" +#include "configuration_interface.h" +#include "gnss_sdr_flags.h" +#include "gnss_sdr_string_literals.h" +#include // for std::max +#include // for std::chrono +#include // for std::floor +#include // for std::exception +#include // for std::cout + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#endif + +using namespace std::string_literals; + +Fmcomms5SignalSourceFPGA::Fmcomms5SignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, unsigned int out_stream, + Concurrent_Queue *queue __attribute__((unused))) + : SignalSourceBase(configuration, role, "FMCOMMS5_Signal_Source_FPGA"s), + gain_mode_rx1_(configuration->property(role + ".gain_mode_rx1", default_gain_mode)), + gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)), + rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)), + filter_filename_(configuration->property(role + ".filter_filename", filter_file_)), + rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)), + rf_gain_rx2_(configuration->property(role + ".gain_rx2", default_manual_gain_rx2)), + freq0_(configuration->property(role + ".freq0", static_cast(GPS_L1_FREQ_HZ))), + freq1_(configuration->property(role + ".freq1", static_cast(GPS_L5_FREQ_HZ))), + sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)), + bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)), + Fpass_(configuration->property(role + ".Fpass", static_cast(0.0))), + Fstop_(configuration->property(role + ".Fstop", static_cast(0.0))), + in_stream_(in_stream), + out_stream_(out_stream), + item_size_(sizeof(int8_t)), + filter_auto_(configuration->property(role + ".filter_auto", false)), + quadrature_(configuration->property(role + ".quadrature", true)), + rf_dc_(configuration->property(role + ".rf_dc", true)), + bb_dc_(configuration->property(role + ".bb_dc", true)), + rx1_enable_(configuration->property(role + ".rx1_enable", true)), + rx2_enable_(configuration->property(role + ".rx2_enable", true)), + enable_dynamic_bit_selection_(configuration->property(role + ".enable_dynamic_bit_selection", true)), + enable_ovf_check_buffer_monitor_active_(true), + dump_(configuration->property(role + ".dump", false)), +#if USE_GLOG_AND_GFLAGS + rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)) +#else + rf_shutdown_(configuration->property(role + ".rf_shutdown", absl::GetFlag(FLAGS_rf_shutdown))) +#endif +{ + const bool enable_rx1_band((configuration->property("Channels_1C.count", 0) > 0) || + (configuration->property("Channels_1B.count", 0) > 0)); + const bool enable_rx2_band((configuration->property("Channels_L2.count", 0) > 0) || + (configuration->property("Channels_L5.count", 0) > 0) || + (configuration->property("Channels_5X.count", 0) > 0)); + + const uint32_t num_freq_bands = ((enable_rx1_band == true) and (enable_rx2_band == true)) ? 2 : 1; + + if (filter_auto_) + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Auto")); + } + else + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); + } + + switch_fpga = std::make_shared(); + switch_fpga->set_switch_position(switch_to_real_time_mode); + + std::cout << "Sample rate: " << sample_rate_ << " Sps\n"; + + // some basic checks + if ((rf_port_select_ != "A_BALANCED") && (rf_port_select_ != "B_BALANCED") && (rf_port_select_ != "A_N") && (rf_port_select_ != "B_N") && (rf_port_select_ != "B_P") && (rf_port_select_ != "C_N") && (rf_port_select_ != "C_P") && (rf_port_select_ != "TX_MONITOR1") && (rf_port_select_ != "TX_MONITOR2") && (rf_port_select_ != "TX_MONITOR1_2")) + { + std::cout << "Configuration parameter rf_port_select should take one of these values:\n"; + std::cout << " A_BALANCED, B_BALANCED, A_N, B_N, B_P, C_N, C_P, TX_MONITOR1, TX_MONITOR2, TX_MONITOR1_2\n"; + std::cout << "Error: provided value rf_port_select=" << rf_port_select_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_port_select=" << default_rf_port_select << '\n'; + rf_port_select_ = default_rf_port_select; + LOG(WARNING) << "Invalid configuration value for rf_port_select parameter. Set to rf_port_select=" << default_rf_port_select; + } + + if ((gain_mode_rx1_ != "manual") && (gain_mode_rx1_ != "slow_attack") && (gain_mode_rx1_ != "fast_attack") && (gain_mode_rx1_ != "hybrid")) + { + std::cout << "Configuration parameter gain_mode_rx1 should take one of these values:\n"; + std::cout << " manual, slow_attack, fast_attack, hybrid\n"; + std::cout << "Error: provided value gain_mode_rx1=" << gain_mode_rx1_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value gain_mode_rx1=" << default_gain_mode << '\n'; + gain_mode_rx1_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx1 parameter. Set to gain_mode_rx1=" << default_gain_mode; + } + + if ((gain_mode_rx2_ != "manual") && (gain_mode_rx2_ != "slow_attack") && (gain_mode_rx2_ != "fast_attack") && (gain_mode_rx2_ != "hybrid")) + { + std::cout << "Configuration parameter gain_mode_rx2 should take one of these values:\n"; + std::cout << " manual, slow_attack, fast_attack, hybrid\n"; + std::cout << "Error: provided value gain_mode_rx2=" << gain_mode_rx2_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value gain_mode_rx2=" << default_gain_mode << '\n'; + gain_mode_rx2_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx2 parameter. Set to gain_mode_rx2=" << default_gain_mode; + } + + if (gain_mode_rx1_ == "manual") + { + if (rf_gain_rx1_ > 73.0 || rf_gain_rx1_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx1 should take values between -1.0 and 73 dB\n"; + std::cout << "Error: provided value rf_gain_rx1=" << rf_gain_rx1_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_gain_rx1=" << default_manual_gain_rx1 << '\n'; + rf_gain_rx1_ = default_manual_gain_rx1; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx1 parameter. Set to rf_gain_rx1=" << default_manual_gain_rx1; + } + } + + if (gain_mode_rx2_ == "manual") + { + if (rf_gain_rx2_ > 73.0 || rf_gain_rx2_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx2 should take values between -1.0 and 73 dB\n"; + std::cout << "Error: provided value rf_gain_rx2=" << rf_gain_rx2_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_gain_rx2=" << default_manual_gain_rx2 << '\n'; + rf_gain_rx2_ = default_manual_gain_rx2; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx2 parameter. Set to rf_gain_rx2=" << default_manual_gain_rx2; + } + } + + if ((filter_source_ != "Off") && (filter_source_ != "Auto") && (filter_source_ != "File") && (filter_source_ != "Design")) + { + std::cout << "Configuration parameter filter_source should take one of these values:\n"; + std::cout << " Off: Disable filter\n"; + std::cout << " Auto: Use auto-generated filters\n"; + std::cout << " File: User-provided filter in filter_filename parameter\n"; + std::cout << " Design: Create filter from Fpass, Fstop, sampling_frequency and bandwidth parameters\n"; + std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value filter_source=Off\n"; + filter_source_ = std::string("Off"); + LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off"; + } + + if (bandwidth_ < 200000 || bandwidth_ > 56000000) + { + std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz\n"; + std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value bandwidth=" << default_bandwidth << '\n'; + bandwidth_ = default_bandwidth; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=" << default_bandwidth; + } + + if (enable_rx1_band) + { + std::cout << "LO 0 frequency : " << freq0_ << " Hz\n"; + } + if (enable_rx2_band) + { + std::cout << "LO 1 frequency : " << freq1_ << " Hz\n"; + } + try + { + config_ad9361_rx_local(bandwidth_, + sample_rate_, + freq0_, + freq1_, + rf_port_select_, + rx1_enable_, + rx2_enable_, + gain_mode_rx1_, + gain_mode_rx2_, + rf_gain_rx1_, + rf_gain_rx2_, + quadrature_, + rf_dc_, + bb_dc_, + filter_source_, + filter_filename_, + Fpass_, + Fstop_); + } + catch (const std::runtime_error &e) + { + std::cerr << "Exception cached when configuring the RX chain: " << e.what() << '\n'; + return; + } + + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + + buffer_monitor_fpga = std::make_shared(num_freq_bands, dump_, dump_filename); + thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); }); + + + // dynamic bits selection + if (enable_dynamic_bit_selection_) + { + dynamic_bit_selection_fpga = std::make_shared(enable_rx1_band, enable_rx2_band); + thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); + } + + if (in_stream_ > 0) + { + LOG(ERROR) << "A signal source does not have an input stream"; + } + if (out_stream_ > 1) + { + LOG(ERROR) << "This implementation only supports one output stream"; + } +} + + +Fmcomms5SignalSourceFPGA::~Fmcomms5SignalSourceFPGA() +{ + /* cleanup and exit */ + + if (rf_shutdown_) + { + std::cout << "* Disabling RX streaming channels\n"; + if (!disable_ad9361_rx_local()) + { + LOG(WARNING) << "Problem shutting down the AD9361 RX channels"; + } + } + + // disable buffer overflow checking and buffer monitoring + std::unique_lock lock_buffer_monitor(buffer_monitor_mutex); + enable_ovf_check_buffer_monitor_active_ = false; + lock_buffer_monitor.unlock(); + + if (thread_buffer_monitor.joinable()) + { + thread_buffer_monitor.join(); + } + + std::unique_lock lock_dyn_bit_sel(dynamic_bit_selection_mutex); + bool bit_selection_enabled = enable_dynamic_bit_selection_; + lock_dyn_bit_sel.unlock(); + + if (bit_selection_enabled == true) + { + std::unique_lock lock(dynamic_bit_selection_mutex); + enable_dynamic_bit_selection_ = false; + lock.unlock(); + + if (thread_dynamic_bit_selection.joinable()) + { + thread_dynamic_bit_selection.join(); + } + } +} + + +void Fmcomms5SignalSourceFPGA::run_dynamic_bit_selection_process() +{ + bool dynamic_bit_selection_active = true; + + while (dynamic_bit_selection_active) + { + // setting the bit selection to the top bits + dynamic_bit_selection_fpga->bit_selection(); + std::this_thread::sleep_for(std::chrono::milliseconds(Gain_control_period_ms)); + std::unique_lock lock(dynamic_bit_selection_mutex); + if (enable_dynamic_bit_selection_ == false) + { + dynamic_bit_selection_active = false; + } + lock.unlock(); + } +} + + +void Fmcomms5SignalSourceFPGA::run_buffer_monitor_process() +{ + bool enable_ovf_check_buffer_monitor_active = true; + + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitoring_initial_delay_ms)); + + while (enable_ovf_check_buffer_monitor_active) + { + buffer_monitor_fpga->check_buffer_overflow_and_monitor_buffer_status(); + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitor_period_ms)); + std::unique_lock lock(buffer_monitor_mutex); + if (enable_ovf_check_buffer_monitor_active_ == false) + { + enable_ovf_check_buffer_monitor_active = false; + } + lock.unlock(); + } +} + + +void Fmcomms5SignalSourceFPGA::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to connect"; +} + + +void Fmcomms5SignalSourceFPGA::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to disconnect"; +} + + +gr::basic_block_sptr Fmcomms5SignalSourceFPGA::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + return {}; +} + + +gr::basic_block_sptr Fmcomms5SignalSourceFPGA::get_right_block() +{ + return {}; +} diff --git a/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.h b/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.h new file mode 100644 index 000000000..1bdcf4e6f --- /dev/null +++ b/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.h @@ -0,0 +1,135 @@ +/*! + * \file fmcomms5_signal_source_fpga.h + * \brief signal source for the Analog Devices FMCOMMS5 directly connected + * to the FPGA accelerators. + * This source implements only the AD9361 control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * Please use the fmcomms2 source if conventional SDR acquisition and tracking + * is selected in the configuration file. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_FMCOMMS5_SIGNAL_SOURCE_FPGA_H +#define GNSS_SDR_FMCOMMS5_SIGNAL_SOURCE_FPGA_H + +#include "concurrent_queue.h" +#include "fpga_buffer_monitor.h" +#include "fpga_dma-proxy.h" +#include "fpga_dynamic_bit_selection.h" +#include "fpga_switch.h" +#include "gnss_block_interface.h" +#include "signal_source_base.h" +#include +#include +#include +#include +#include +#include + + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_adapters + * \{ */ + + +class ConfigurationInterface; + +class Fmcomms5SignalSourceFPGA : public SignalSourceBase +{ +public: + Fmcomms5SignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, + unsigned int out_stream, Concurrent_Queue *queue); + + ~Fmcomms5SignalSourceFPGA(); + + inline size_t item_size() override + { + return item_size_; + } + + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + +private: + const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat"); + const std::string default_rf_port_select = std::string("A_BALANCED"); + const std::string default_gain_mode = std::string("slow_attack"); + const double default_tx_attenuation_db = -10.0; + const double default_manual_gain_rx1 = 64.0; + const double default_manual_gain_rx2 = 64.0; + const uint64_t default_bandwidth = 12500000; + + // perform dynamic bit selection every 500 ms by default + const uint32_t Gain_control_period_ms = 500; + // check buffer overflow and perform buffer monitoring every 1s by default + const uint32_t buffer_monitor_period_ms = 1000; + // buffer overflow and buffer monitoring initial delay + const uint32_t buffer_monitoring_initial_delay_ms = 2000; + // sample block size when running in post-processing mode + const int sample_block_size = 16384; + const int32_t switch_to_real_time_mode = 2; + + void run_dynamic_bit_selection_process(); + void run_buffer_monitor_process(); + + std::thread thread_dynamic_bit_selection; + std::thread thread_buffer_monitor; + + std::shared_ptr switch_fpga; + std::shared_ptr dynamic_bit_selection_fpga; + std::shared_ptr buffer_monitor_fpga; + + std::mutex dynamic_bit_selection_mutex; + std::mutex buffer_monitor_mutex; + + std::string gain_mode_rx1_; + std::string gain_mode_rx2_; + std::string rf_port_select_; + std::string filter_file_; + std::string filter_source_; + std::string filter_filename_; + + double rf_gain_rx1_; + double rf_gain_rx2_; + + uint64_t freq0_; // frequency of local oscillator for ADRV9361-A + uint64_t freq1_; // frequency of local oscillator for ADRV9361-B + uint64_t sample_rate_; + uint64_t bandwidth_; + + float Fpass_; + float Fstop_; + uint32_t in_stream_; + uint32_t out_stream_; + + size_t item_size_; + + bool filter_auto_; + bool quadrature_; + bool rf_dc_; + bool bb_dc_; + bool rx1_enable_; + bool rx2_enable_; + bool enable_dynamic_bit_selection_; + bool enable_ovf_check_buffer_monitor_active_; + bool dump_; + bool rf_shutdown_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_FMCOMMS5_SIGNAL_SOURCE_FPGA_H diff --git a/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.cc b/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.cc new file mode 100644 index 000000000..788b50e77 --- /dev/null +++ b/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.cc @@ -0,0 +1,467 @@ +/*! + * \file max2771_evkit_signal_source_fpga.cc + * \brief Signal source for the MAX2771EVKIT evaluation board connected directly + * to FPGA accelerators. + * This source implements only the MAX2771 control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "max2771_evkit_signal_source_fpga.h" +#include "GPS_L1_CA.h" +#include "GPS_L2C.h" +#include "GPS_L5.h" +#include "configuration_interface.h" +#include "gnss_sdr_flags.h" +#include "gnss_sdr_string_literals.h" +#include // for std::max +#include // for std::chrono +#include // for std::floor +#include // for std::exception +#include // for std::cout +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#endif + +using namespace std::string_literals; + +MAX2771EVKITSignalSourceFPGA::MAX2771EVKITSignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, unsigned int out_stream, + Concurrent_Queue *queue __attribute__((unused))) + : SignalSourceBase(configuration, role, "MAX2771_EVKIT_Signal_Source_FPGA"s), + freq_(configuration->property(role + ".freq", static_cast(GPS_L1_FREQ_HZ))), + sample_rate_(configuration->property(role + ".sampling_frequency", default_sampling_rate)), + in_stream_(in_stream), + out_stream_(out_stream), + bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)), + filter_order_(configuration->property(role + ".filter_order", default_filter_order)), + gain_in_(configuration->property(role + ".PGA_gain", default_PGA_gain_value)), + item_size_(sizeof(int8_t)), + chipen_(true), + if_filter_gain_(configuration->property(role + ".enable_IF_filter_gain", true)), + LNA_active_(configuration->property(role + ".LNA_active", false)), + enable_agc_(configuration->property(role + ".enable_AGC", true)), + enable_ovf_check_buffer_monitor_active_(true), + dump_(configuration->property(role + ".dump", false)), +#if USE_GLOG_AND_GFLAGS + rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)) +#else + rf_shutdown_(configuration->property(role + ".rf_shutdown", absl::GetFlag(FLAGS_rf_shutdown))) +#endif +{ + // some basic checks + if (freq_ != GPS_L1_FREQ_HZ and freq_ != GPS_L2_FREQ_HZ and freq_ != GPS_L5_FREQ_HZ) + { + std::cout << "Configuration parameter freq should take values " << GPS_L1_FREQ_HZ << ", " << GPS_L2_FREQ_HZ << ", or " << GPS_L5_FREQ_HZ << "\n"; + std::cout << "Error: provided value freq = " << freq_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value freq = " << GPS_L1_FREQ_HZ << '\n'; + LOG(WARNING) << "Invalid configuration value for freq parameter. Set to freq = " << GPS_L1_FREQ_HZ; + freq_ = GPS_L1_FREQ_HZ; + } + if (sample_rate_ != 4092000 and sample_rate_ != 8184000 and sample_rate_ != 16368000 and sample_rate_ != 32736000) + { + std::cout << "Configuration parameter sampling_frequency should take values 4092000, 8184000, 16368000, or 32736000\n"; + std::cout << "Error: provided value sampling_frequency = " << sample_rate_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value sampling_frequency = " << default_sampling_rate << '\n'; + LOG(WARNING) << "Invalid configuration value for sampling_frequency parameter. Set to sampling_frequency = " << default_sampling_rate; + sample_rate_ = default_sampling_rate; + } + if (bandwidth_ != 2500000 and bandwidth_ != 4200000 and bandwidth_ != 8700000 and bandwidth_ != 16400000 and bandwidth_ != 23400000 and bandwidth_ != 36000000) + { + std::cout << "Configuration parameter bandwidth can only take the following values: 2500000, 4200000, 8700000, 16400000, 23400000, and 36000000 Hz\n"; + std::cout << "Error: provided value bandwidth = " << bandwidth_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value bandwidth = " << default_bandwidth << '\n'; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth = " << default_bandwidth; + bandwidth_ = default_bandwidth; + } + if (filter_order_ != 3 and filter_order_ != 5) + { + std::cout << "Configuration parameter filter_order should take values 3 or 5\n"; + std::cout << "Error: provided value filter_order = " << filter_order_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value filter_order = " << default_filter_order << '\n'; + LOG(WARNING) << "Invalid configuration value for filter_order parameter. Set to filter_order = " << default_filter_order; + filter_order_ = default_filter_order; + } + if (gain_in_ > max_PGA_gain_value) + { + std::cout << "Configuration parameter PGA_gain should be up to " << max_PGA_gain_value << "\n"; + std::cout << "Error: provided value PGA_gain = " << gain_in_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value PGA_gain = " << default_PGA_gain_value << '\n'; + LOG(WARNING) << "Invalid configuration value for PGA_gain parameter. Set to PGA_gain = " << default_PGA_gain_value; + gain_in_ = default_PGA_gain_value; + } + + std::vector register_values = setup_regs(); + + spidev_fpga = std::make_shared(); + + if (spidev_fpga->SPI_open()) + { + std::cerr << "Cannot open SPI device\n"; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + + if (configure(register_values)) + { + std::cerr << "Error configuring the MAX2771 device " << '\n'; + } + + if (spidev_fpga->SPI_close()) + { + std::cerr << "Error closing SPI device " << '\n'; + } + + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + + buffer_monitor_fpga = std::make_shared(NUM_FREQ_BANDS, dump_, dump_filename); + thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); }); + + if (in_stream_ > 0) + { + LOG(ERROR) << "A signal source does not have an input stream"; + } + if (out_stream_ > 1) + { + LOG(ERROR) << "This implementation only supports one output stream"; + } +} + +std::vector MAX2771EVKITSignalSourceFPGA::setup_regs(void) +{ + std::vector register_values = std::vector(MAX2771_NUM_REGS); + + + uint32_t LNA_mode = (LNA_active_) ? 0x0 : 0x2; + + uint32_t Filter_Bandwidth; + + switch (bandwidth_) + { + case 2500000: + Filter_Bandwidth = 0x0; + break; + case 4200000: + Filter_Bandwidth = 0x2; + break; + case 8700000: + Filter_Bandwidth = 0x1; + break; + case 16400000: + Filter_Bandwidth = 0x7; + break; + case 23400000: + Filter_Bandwidth = 0x3; + break; + case 36000000: + Filter_Bandwidth = 0x4; + break; + default: + Filter_Bandwidth = 0x0; // default bandwidth + } + + uint32_t chipen_select = (chipen_) ? 0x1 : 0x0; + uint32_t Filter_order_sel = (filter_order_ == 5) ? 0x0 : 0x1; + uint32_t IF_filter_gain_sel = (if_filter_gain_) ? 0x1 : 0x0; + + register_values[0] = // configuration 1 register + (chipen_select << 31) + + (IDLE << 30) + + (0x8 << 26) + // reserved + (0x8 << 22) + // reserved + (0x2 << 20) + // reserved + (0x1 << 18) + // reserved + (MIXPOLE << 17) + + (LNA_mode << 15) + + (MIXERMODE << 13) + + (FCEN << 6) + + (Filter_Bandwidth << 3) + + (Filter_order_sel << 2) + + (FCENX << 1) + + IF_filter_gain_sel; + + uint32_t AGC_mode = (enable_agc_) ? 0x0 : 0x2; + + register_values[1] = // configuration 2 register + (0x0 << 31) + // reserved + (0x1 << 29) + // reserved + (ANAIMON << 28) + + (IQEN << 27) + + (GAINREF << 15) + + (SPI_SDIO_CONFIG << 13) + + (AGC_mode << 11) + + (FORMAT << 9) + + (BITS << 6) + + (DRVCFG << 4) + + (0x1 << 3) + // reserved + (0x0 << 2) + // reserved + DIEID; + + register_values[2] = // configuration 3 register + (0x0 << 28) + // reserved + (gain_in_ << 22) + + (0x1 << 21) + // reserved + (HILOADEN << 20) + + (0x1 << 19) + // reserved + (0x1 << 18) + // reserved + (0x1 << 17) + // reserved + (0x1 << 16) + // reserved + (FHIPEN << 15) + + (0x0 << 14) + // reserved + (PGAIEN << 13) + + (PGAQEN << 12) + + (STRMEN << 11) + + (STRMSTART << 10) + + (STRMSTOP << 9) + + (0x7 << 6) + // reserved + (STRMBITS << 4) + + (STAMPEN << 3) + + (TIMESYNCEN << 2) + + (DATASYNCEN << 1) + + STRMRST; + + uint32_t clock_out_div_ratio; + + switch (sample_rate_) + { + case 4092000: + clock_out_div_ratio = 0x1; // XTAL frequency /4 + break; + case 8184000: + clock_out_div_ratio = 0x2; // XTAL frequency /2 + break; + case 16368000: + clock_out_div_ratio = 0x3; // XTAL frequency + break; + case 32736000: + clock_out_div_ratio = 0x0; // XTAL Frequency x2 + break; + default: + clock_out_div_ratio = 0x1; // default XTAL frequency + } + + register_values[3] = // PLL configuration register + (clock_out_div_ratio << 29) + + (LOBAND << 28) + + (0x1 << 27) + // reserved + (0x0 << 26) + // reserved + (0x0 << 25) + // reserved + (REFOUTEN << 24) + + (0x1 << 23) + // reserved + (0x0 << 21) + // reserved + (IXTAL << 19) + + (0x10 << 14) + // reserved + (0x0 << 13) + // reserved + (0x0 << 10) + // reserved + (ICP << 9) + + (0x0 << 8) + // reserved + (0x0 << 7) + // reserved + (0x0 << 4) + // reserved + (INT_PLL << 3) + + (PWRSAV << 2) + + (0x0 << 1) + // reserved + 0x0; // reserved + + uint32_t freq_sel; + switch (freq_) + { + case static_cast(GPS_L1_FREQ_HZ): + freq_sel = 0x604; + break; + case static_cast(GPS_L2_FREQ_HZ): + freq_sel = 0x4B0; + break; + case static_cast(GPS_L5_FREQ_HZ): + freq_sel = 0x47E; + break; + default: + freq_sel = 0x604; + } + + register_values[4] = // PLL integer division register + (0x0 << 28) + // reserved + (freq_sel << 13) + + (RDIV << 3) + + 0x0; // reserved + + register_values[5] = // PLL fractional division register + (0x0 << 28) + // reserved + (FDIV << 8) + + (0x7 << 4) + // reserved + (0x0 << 3) + // reserved + (0x0 << 2) + // reserved + (0x0 << 1) + // reserved + 0x0; // reserved + + register_values[6] = // DSP interface register + (0x0 << 28) + // reserved + 0x8000000; // reserved + + register_values[7] = // clock configuration 1 register + (0x0 << 29) + // reserved + (EXTADCCLK << 28) + + (REFCLK_L_CNT << 16) + + (REFCLK_M_CNT << 4) + + (FCLKIN << 3) + + (ADCCLK << 2) + + (0x1 << 1) + // reserved + MODE; + + register_values[8] = TEST_MODE_1_REG_VAL; // test mode 1 register + + register_values[9] = TEST_MODE_2_REG_VAL; // test mode 2 register + + register_values[10] = // clock configuration 2 register + (0x0 << 29) + // reserved + (0x0 << 28) + // reserved + (ADCCLK_L_CNT << 16) + + (ADCCLK_M_CNT << 4) + + (PRE_FRACDIV_SEL << 3) + + (CLKOUT_SEL << 2) + + 0x0; // reserved + + return register_values; +} + + +bool MAX2771EVKITSignalSourceFPGA::configure(std::vector register_values) +{ + // write the registers + std::cerr << "Configuring MAX2771 registers" << std::endl; + uint32_t status = 0; + for (uint32_t k = 0; k < register_values.size(); k++) + { + status = spidev_fpga->write_reg32(k, register_values[k]); + if (status) + { + std::cerr << "Error writing the MAX2771 registers" << std::endl; + break; + } + } + + // Read the registers and verify that the values are correctly written + std::vector reg_read = std::vector(register_values.size()); + + for (uint8_t n = 0; n < register_values.size(); ++n) + { + status = spidev_fpga->read_reg32(n, ®_read[n]); + if (status) + { + std::cerr << "Error reading the MAX2771 registers" << std::endl; + return status; + } + else + { + if (reg_read[n] != register_values[n]) + { + std::cerr << "Error: Failed to verify the MAX2771 registers " << std::endl; + return -1; + } + } + } + + return 0; +} + +MAX2771EVKITSignalSourceFPGA::~MAX2771EVKITSignalSourceFPGA() +{ + /* cleanup and exit */ + + if (rf_shutdown_) + { + chipen_ = false; + std::cout << "* MAX2771 Disabling RX streaming channels\n"; + std::vector register_values = setup_regs(); + + if (spidev_fpga->SPI_open()) + { + std::cerr << "Cannot open SPI device\n"; + return; + } + + + if (configure(register_values)) + { + std::cerr << "Error disabling the MAX2771 device " << '\n'; + } + + if (spidev_fpga->SPI_close()) + { + std::cerr << "Error closing SPI device " << '\n'; + } + } + + // disable buffer overflow checking and buffer monitoring + std::unique_lock lock_buffer_monitor(buffer_monitor_mutex); + enable_ovf_check_buffer_monitor_active_ = false; + lock_buffer_monitor.unlock(); + + if (thread_buffer_monitor.joinable()) + { + thread_buffer_monitor.join(); + } +} + + +void MAX2771EVKITSignalSourceFPGA::run_buffer_monitor_process() +{ + bool enable_ovf_check_buffer_monitor_active = true; + + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitoring_initial_delay_ms)); + + while (enable_ovf_check_buffer_monitor_active) + { + buffer_monitor_fpga->check_buffer_overflow_and_monitor_buffer_status(); + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitor_period_ms)); + std::unique_lock lock(buffer_monitor_mutex); + if (enable_ovf_check_buffer_monitor_active_ == false) + { + enable_ovf_check_buffer_monitor_active = false; + } + lock.unlock(); + } +} + + +void MAX2771EVKITSignalSourceFPGA::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to connect"; +} + + +void MAX2771EVKITSignalSourceFPGA::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to disconnect"; +} + + +gr::basic_block_sptr MAX2771EVKITSignalSourceFPGA::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + return {}; +} + + +gr::basic_block_sptr MAX2771EVKITSignalSourceFPGA::get_right_block() +{ + return {}; +} diff --git a/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.h b/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.h new file mode 100644 index 000000000..3008aa384 --- /dev/null +++ b/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.h @@ -0,0 +1,164 @@ +/*! + * \file max2771_evkit_signal_source_fpga.h + * \brief Signal source for the MAX2771EVKIT evaluation board connected directly + * to FPGA accelerators. + * This source implements only the MAX2771 control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_MAX2771_EVKIT_SIGNAL_SOURCE_FPGA_H +#define GNSS_SDR_MAX2771_EVKIT_SIGNAL_SOURCE_FPGA_H + +#include "command_event.h" +#include "concurrent_queue.h" +#include "fpga_buffer_monitor.h" +#include "fpga_spidev.h" +#include "gnss_block_interface.h" +#include "signal_source_base.h" +#include // for pmt::pmt_t +#include // for fixed-width integer types +#include // for smart pointers +#include // for mutex +#include // for strings +#include // for threads +#include // for std::vector + + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_adapters + * \{ */ + + +class ConfigurationInterface; + +class MAX2771EVKITSignalSourceFPGA : public SignalSourceBase +{ +public: + MAX2771EVKITSignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, + unsigned int out_stream, Concurrent_Queue *queue); + + ~MAX2771EVKITSignalSourceFPGA(); + + std::vector setup_regs(void); + + + inline size_t item_size() override + { + return item_size_; + } + + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + +private: + const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat"); + const uint64_t default_bandwidth = 2500000; + const uint32_t default_filter_order = 5; + const uint64_t default_sampling_rate = 4092000; + const uint32_t default_PGA_gain_value = 0x3A; // default PGA gain when AGC is off + // max PGA gain value + const uint32_t max_PGA_gain_value = 0x3F; + // check buffer overflow and perform buffer monitoring every 1s by default + const uint32_t buffer_monitor_period_ms = 1000; + // buffer overflow and buffer monitoring initial delay + const uint32_t buffer_monitoring_initial_delay_ms = 2000; + // MAX2771 number of configuration registers + const uint32_t MAX2771_NUM_REGS = 11; + // MAX2771 configuration register fields + const uint32_t NUM_FREQ_BANDS = 1; + const uint32_t IDLE = 0x0; // Idle mode disabled + const uint32_t MIXPOLE = 0x0; // set the passive filter pole at mixer output at 13 MHz. + const uint32_t MIXERMODE = 0x0; // L1 band enabled + const uint32_t FCEN = 0x58; // Center frequency not used when in low-pass filter mode. Set to default value. + const uint32_t FCENX = 0x0; // POlyphase filter selection set to Lowpass filter + const uint32_t ANAIMON = 0x0; // analog monitor disabled + const uint32_t IQEN = 0x1; // I and Q channels enable + const uint32_t GAINREF = 0xAA; // AGC Gain ref + const uint32_t SPI_SDIO_CONFIG = 0x0; // SPI SDIO config when tri-stated: nothing applied + const uint32_t FORMAT = 0x1; // sign and magnitude + const uint32_t BITS = 0x2; // number of bits in the ADC = 2 + const uint32_t DRVCFG = 0x0; // output driver configuration = CMOS Logic + const uint32_t DIEID = 0x0; // identifies version of IC + const uint32_t HILOADEN = 0x0; // disable output driver for high loads + const uint32_t FHIPEN = 0x1; // enable highpass coupling between filter and PGA. + const uint32_t PGAIEN = 0x1; // I-Channel PGA Enable + const uint32_t PGAQEN = 0x1; // Q-Channel PGA Enable + const uint32_t STRMEN = 0x0; // disable DSP interface for serial streaming of data + const uint32_t STRMSTART = 0x0; // the rising edge of this bit enables data streaming to the output, clock, data, sync and frame sync outputs. + const uint32_t STRMSTOP = 0x0; // the rising edge of this bit disables data streaming to the output, clock, data sync and frame sync outputs. + const uint32_t STRMBITS = 0x1; // number of bits to be streamed: I MSB, I LSB + const uint32_t STAMPEN = 0x1; // enable frame number insertion + const uint32_t TIMESYNCEN = 0x1; // enable the output of the time sync pulses at all times when streaming is enabled. + const uint32_t DATASYNCEN = 0x0; // disable the sync pulses at the DATASYNC output + const uint32_t STRMRST = 0x0; // counter reset not active + const uint32_t LOBAND = 0x0; // L1 band + const uint32_t REFOUTEN = 0x1; // Output clock buffer enable + const uint32_t IXTAL = 0x1; // XTAL osscillator/buffer set to normal current + const uint32_t ICP = 0x0; // charge pump current selection set to 0.5 mA + const uint32_t INT_PLL = 0x1; // PLL mode set to integer-N PLL + const uint32_t PWRSAV = 0x0; // PLL power save mode disabled + const uint32_t RDIV = 0x10; // Set the PLL reference division ratio such that the L1 band is tuned to 1575.42 Mhz + const uint32_t FDIV = 0x80000; // PLL fractional division ratio not used. Set to default value + const uint32_t EXTADCCLK = 0x0; // use internally generated clock + const uint32_t REFCLK_L_CNT = 0x100; // set the L counter of the reference clock configuration to its default value + const uint32_t REFCLK_M_CNT = 0x61B; // set the M counter of the reference clock configuration to its default value + const uint32_t FCLKIN = 0x0; // fractional clock divider set to default value + const uint32_t ADCCLK = 0x0; // ADC clock selection set to reference clock divider/multiplier + const uint32_t MODE = 0x0; // DSP interface mode selection + const uint32_t ADCCLK_L_CNT = 0x100; // set the L counter of the ADC clock configuration to its default value + const uint32_t ADCCLK_M_CNT = 0x61B; // set the M counter of the ADC clock configuration to its default value + const uint32_t PRE_FRACDIV_SEL = 0x0; // bypass fractional clock divider + const uint32_t CLKOUT_SEL = 0x1; // CLKOUT selection set to ADC clock + // MAX2771 configuration register registers + const uint32_t TEST_MODE_1_REG_VAL = 0x01E0F401; // reserved + const uint32_t TEST_MODE_2_REG_VAL = 0x00000002; + + bool configure(std::vector register_values); + void run_buffer_monitor_process(); + + + std::thread thread_buffer_monitor; + + std::shared_ptr buffer_monitor_fpga; + std::shared_ptr spidev_fpga; + + std::mutex buffer_monitor_mutex; + + uint64_t freq_; // frequency of local oscillator + uint64_t sample_rate_; + + uint32_t in_stream_; + uint32_t out_stream_; + uint32_t bandwidth_; // 2500000, 4200000, 8700000, 16400000, 23400000, 36000000 + uint32_t filter_order_; // 3, 5 + uint32_t gain_in_; // 0 to 0x3F + + size_t item_size_; // 1 + + bool chipen_; // chip enable + bool if_filter_gain_; // true, false + bool LNA_active_; // true, false + bool enable_agc_; // true, false + bool enable_ovf_check_buffer_monitor_active_; + bool dump_; + bool rf_shutdown_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_MAX2771_EVKIT_SIGNAL_SOURCE_FPGA_H diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index 2b0eb6a86..3506dc4f7 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -12,17 +12,27 @@ if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad9361_manager.h) endif() -if(ENABLE_FPGA OR ENABLE_AD9361) +if(ENABLE_MAX2771) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_spidev.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_spidev.h) +endif() + +if(ENABLE_FPGA) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_switch.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_switch.h) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dynamic_bit_selection.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dynamic_bit_selection.h) - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h) +endif() + +if(ENABLE_DMA_PROXY) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dma-proxy.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dma-proxy.h) endif() +if((ENABLE_FPGA AND ENABLE_AD9361) OR ENABLE_MAX2771) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h) +endif() if(ENABLE_PLUTOSDR) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_samples.cc) diff --git a/src/algorithms/signal_source/libs/ad936x_iio_custom.cc b/src/algorithms/signal_source/libs/ad936x_iio_custom.cc index 2869081f2..72461bafd 100644 --- a/src/algorithms/signal_source/libs/ad936x_iio_custom.cc +++ b/src/algorithms/signal_source/libs/ad936x_iio_custom.cc @@ -13,6 +13,7 @@ * ----------------------------------------------------------------------------- */ #include "ad936x_iio_custom.h" +#include "display.h" #include #include #include @@ -44,6 +45,7 @@ ad936x_iio_custom::ad936x_iio_custom(int debug_level_, int log_level_) n_channels = 0; } + ad936x_iio_custom::~ad936x_iio_custom() { // disable TX @@ -59,11 +61,13 @@ void ad936x_iio_custom::set_gnsstime_queue(std::shared_ptr> queue) { Pps_queue = std::move(queue); } + bool ad936x_iio_custom::initialize_device(std::string pluto_device_uri, std::string board_type) { // Find devices @@ -125,7 +129,6 @@ bool ad936x_iio_custom::initialize_device(std::string pluto_device_uri, std::str return false; } - phy = iio_context_find_device(ctx, "ad9361-phy"); if (phy == NULL) @@ -328,7 +331,6 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_, configure_params(dds_dev, params_dds); } - return true; } @@ -345,6 +347,7 @@ bool ad936x_iio_custom::check_device() } } + bool ad936x_iio_custom::get_iio_param(iio_device *dev, const std::string ¶m, std::string &value) { struct iio_channel *chn = 0; @@ -386,6 +389,7 @@ bool ad936x_iio_custom::get_iio_param(iio_device *dev, const std::string ¶m, } } + bool ad936x_iio_custom::read_die_temp(double &temp_c) { std::string temp_mC_str; @@ -410,6 +414,8 @@ bool ad936x_iio_custom::read_die_temp(double &temp_c) return false; } } + + bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, long long sample_rate_, long long freq_, @@ -425,7 +431,6 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, double lo_attenuation_db_, bool high_side_lo_, int tx_lo_channel_) - { if (check_device() == false) return false; @@ -610,14 +615,12 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, std::cerr << "Warning: rf_port_select write returned: " << ret << "\n"; no_errors = false; } - // ret = iio_channel_attr_write_longlong(phy_ch, "rf_bandwidth", bandwidth_); // if (ret < 0) // { // std::cerr << "Warning: rf_bandwidth write returned: " << ret << "\n"; // no_errors = false; // } - long long set_rf_bw; ret = iio_channel_attr_read_longlong(phy_ch, "rf_bandwidth", &set_rf_bw); if (ret < 0) @@ -630,7 +633,6 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, std::cerr << "Info: rf_bandwidth read returned: " << set_rf_bw << " Hz \n"; } - if (setRXGain(0, gain_mode_rx0_, rf_gain_rx0_) == false) { std::cerr << "Info: setRXGain read returned false \n"; @@ -662,14 +664,12 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, std::cerr << "Warning: rf_port_select write returned: " << ret << "\n"; no_errors = false; } - // ret = iio_channel_attr_write_longlong(phy_ch, "rf_bandwidth", bandwidth_); // if (ret < 0) // { // std::cerr << "Warning: rf_bandwidth write returned: " << ret << "\n"; // no_errors = false; // } - long long set_rf_bw; ret = iio_channel_attr_read_longlong(phy_ch, "rf_bandwidth", &set_rf_bw); if (ret < 0) @@ -702,6 +702,7 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, return no_errors; } + bool ad936x_iio_custom::set_rx_frequency(long long freq_hz) { if (check_device() == false) return false; @@ -747,6 +748,7 @@ bool ad936x_iio_custom::get_rx_frequency(long long &freq_hz) return true; } + bool ad936x_iio_custom::setRXGain(int ch_num, std::string gain_mode, double gain_dB) { if (check_device() == false) return false; @@ -779,6 +781,7 @@ bool ad936x_iio_custom::setRXGain(int ch_num, std::string gain_mode, double gain } } + double ad936x_iio_custom::get_rx_gain(int ch_num) { if (check_device() == false) return -1; @@ -817,6 +820,7 @@ bool ad936x_iio_custom::calibrate([[maybe_unused]] int ch, [[maybe_unused]] doub return true; } + void ad936x_iio_custom::monitor_thread_fn() { uint32_t val; @@ -849,11 +853,12 @@ void ad936x_iio_custom::monitor_thread_fn() // } else { if (val & 4) { - std::cout << "WARNING: IIO status register reported overflow!\n"; - LOG(INFO) << "WARNING: IIO status register reported overflow!"; + std::cout + << TEXT_BOLD_RED + << "WARNING: IIO status register reported overflow!\n"; + LOG(WARNING) << "WARNING: IIO status register reported overflow!"; } - /* Clear bits */ if (val) { @@ -867,6 +872,7 @@ void ad936x_iio_custom::monitor_thread_fn() return; } + void ad936x_iio_custom::stop_record() { receive_samples = false; @@ -915,6 +921,7 @@ void ad936x_iio_custom::PlutoTxEnable(bool txon) } } + void ad936x_iio_custom::setPlutoGpo(int p) { char pins[11]; @@ -953,7 +960,6 @@ bool ad936x_iio_custom::select_rf_filter(std::string rf_filter) // 1 Enable // X Enable Mask if Identifier=0xF - if (check_device() == false) return false; // int plutoGpo = 0; int ret; @@ -1006,6 +1012,8 @@ bool ad936x_iio_custom::select_rf_filter(std::string rf_filter) return true; } + + void ad936x_iio_custom::get_PPS_timestamp() { GnssTime tow; @@ -1042,7 +1050,6 @@ void ad936x_iio_custom::get_PPS_timestamp() // record pps rise samplestamp associated to the absolute sample counter // PPS rising edge must be associated with the corresponding uBlox time message (tx once a second) - if (GnssTime_queue->timed_wait_and_pop(tow, 2000) == false) { if (receive_samples == true) @@ -1073,6 +1080,8 @@ void ad936x_iio_custom::get_PPS_timestamp() } } } + + bool ad936x_iio_custom::start_sample_rx(bool ppsmode) { // using queues of smart pointers to preallocated buffers @@ -1118,9 +1127,7 @@ bool ad936x_iio_custom::start_sample_rx(bool ppsmode) // start sample overflow detector overflow_monitor_thread = std::thread(&ad936x_iio_custom::monitor_thread_fn, this); - // start PPS and GNSS Time capture thread - if (ppsmode == true) { capture_time_thread = std::thread(&ad936x_iio_custom::get_PPS_timestamp, this); @@ -1128,16 +1135,19 @@ bool ad936x_iio_custom::start_sample_rx(bool ppsmode) return true; } + void ad936x_iio_custom::pop_sample_buffer(std::shared_ptr ¤t_buffer) { used_buffers.wait_and_pop(current_buffer); } + void ad936x_iio_custom::push_sample_buffer(std::shared_ptr ¤t_buffer) { free_buffers.push(current_buffer); } + void ad936x_iio_custom::capture(const std::vector &channels) { if (check_device() == false) return; diff --git a/src/algorithms/signal_source/libs/fpga_buffer_monitor.cc b/src/algorithms/signal_source/libs/fpga_buffer_monitor.cc index 0b250d131..1f56afbf4 100644 --- a/src/algorithms/signal_source/libs/fpga_buffer_monitor.cc +++ b/src/algorithms/signal_source/libs/fpga_buffer_monitor.cc @@ -25,6 +25,7 @@ #include "fpga_buffer_monitor.h" #include "gnss_sdr_create_directory.h" #include "gnss_sdr_filesystem.h" +#include "uio_fpga.h" #include // for time, localtime #include // for open, O_RDWR, O_SYNC #include // for string, ofstream @@ -40,7 +41,7 @@ #endif -Fpga_buffer_monitor::Fpga_buffer_monitor(const std::string &device_name, +Fpga_buffer_monitor::Fpga_buffer_monitor( uint32_t num_freq_bands, bool dump, std::string dump_filename) @@ -50,10 +51,19 @@ Fpga_buffer_monitor::Fpga_buffer_monitor(const std::string &device_name, d_max_buff_occ_freq_band_1(0), d_dump(dump) { - // open device descriptor - if ((d_device_descriptor = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1) + std::string device_io_name; + + // find the uio device file corresponding to the buffer monitor + if (find_uio_dev_file_name(device_io_name, BUFFER_MONITOR_DEVICE_NAME, 0) < 0) { - LOG(WARNING) << "Cannot open deviceio" << device_name; + std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << BUFFER_MONITOR_DEVICE_NAME << '\n'; + return; + } + + // open device descriptor + if ((d_device_descriptor = open(device_io_name.c_str(), O_RDWR | O_SYNC)) == -1) + { + LOG(WARNING) << "Cannot open deviceio" << device_io_name; } // device memory map diff --git a/src/algorithms/signal_source/libs/fpga_buffer_monitor.h b/src/algorithms/signal_source/libs/fpga_buffer_monitor.h index 00b413e30..7231c5ae3 100644 --- a/src/algorithms/signal_source/libs/fpga_buffer_monitor.h +++ b/src/algorithms/signal_source/libs/fpga_buffer_monitor.h @@ -45,10 +45,13 @@ public: /*! * \brief Constructor */ - explicit Fpga_buffer_monitor(const std::string& device_name, - uint32_t num_freq_bands, + explicit Fpga_buffer_monitor(uint32_t num_freq_bands, bool dump, std::string dump_filename); + // explicit Fpga_buffer_monitor(const std::string& device_name, + // uint32_t num_freq_bands, + // bool dump, + // std::string dump_filename); /*! * \brief Destructor @@ -61,6 +64,7 @@ public: void check_buffer_overflow_and_monitor_buffer_status(); private: + const std::string BUFFER_MONITOR_DEVICE_NAME = std::string("buffer_monitor"); // buffer monitor device name static const size_t FPGA_PAGE_SIZE = 0x1000; static const uint32_t test_register_writeval = 0x55AA; static const uint32_t num_sapmples_per_buffer_element = 2; diff --git a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h index 3f4b73a5a..53729b265 100644 --- a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h @@ -56,7 +56,6 @@ public: void bit_selection(void); private: - const std::string switch_device_name = std::string("AXIS_Switch_v1_0_0"); // Switch UIO device name const std::string dyn_bit_sel_device_name = std::string("dynamic_bits_selector"); // Switch dhnamic bit selector device name static const size_t FPGA_PAGE_SIZE = 0x1000; static const uint32_t Num_bits_ADC = 12; // Number of bits in the ADC diff --git a/src/algorithms/signal_source/libs/fpga_spidev.cc b/src/algorithms/signal_source/libs/fpga_spidev.cc new file mode 100644 index 000000000..f90cf4ac9 --- /dev/null +++ b/src/algorithms/signal_source/libs/fpga_spidev.cc @@ -0,0 +1,131 @@ +/*! + * \file fpga_spidev.cc + * \brief FPGA SPI control. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "fpga_spidev.h" +#include // for memset() +#include // for open(), O_RDWR +#include // for std::cerr +#include // spidev driver +#include // for ioctl() +#include // for close() + + +int Fpga_spidev::SPI_open() +{ + if ((d_fd = open(SPI_DEVICE_NAME.c_str(), O_RDWR)) < 0) + { + std::cerr << "Failed to open the " << SPI_DEVICE_NAME << " device file \n"; + return -1; + } + + int ret; + int32_t mode = 0; + + ret = ioctl(d_fd, SPI_IOC_WR_MODE32, &mode); + if (ret == -1) + { + std::cerr << "can't set spi mode\n"; + return -1; + } + + ret = ioctl(d_fd, SPI_IOC_RD_MODE32, &mode); // le digo al spi "algo" + if (ret == -1) + { + std::cerr << "can't set spi mode\n"; + return -1; + } + + return 0; +} + +int Fpga_spidev::write_reg32(char addr, uint32_t data) +{ + uint8_t data_buffer[2]; + uint8_t recv_buffer[4]; + int res = 0; + struct spi_ioc_transfer xfer[2]; + memset(xfer, 0, sizeof(xfer)); + xfer[0].bits_per_word = 8; + xfer[0].speed_hz = SPI_SPEED; + xfer[1].bits_per_word = 8; + xfer[1].speed_hz = SPI_SPEED; + + memset(&recv_buffer, 0, sizeof(recv_buffer)); + memset(&data_buffer, 0, sizeof(data_buffer)); + + data_buffer[1] = addr << 4 | 0 << 3; + xfer[0].tx_buf = (unsigned long)data_buffer; + xfer[0].len = 2; + + // Would use memcpy but 'data' is in little endian + ((char*)recv_buffer)[0] = ((char*)&data)[3]; + ((char*)recv_buffer)[1] = ((char*)&data)[2]; + ((char*)recv_buffer)[2] = ((char*)&data)[1]; + ((char*)recv_buffer)[3] = ((char*)&data)[0]; + + xfer[1].tx_buf = (unsigned long)recv_buffer; + xfer[1].len = 4; + res = ioctl(d_fd, SPI_IOC_MESSAGE(2), xfer); + if (res < 0) + { + std::cout << "Error sending SPI message\n"; + return res; + } + return 0; +} + +int Fpga_spidev::read_reg32(uint8_t addr, uint32_t* copy_to) +{ + uint8_t data_buffer[2]; + uint8_t recv_buffer[4]; + int res; + struct spi_ioc_transfer xfer[2]; + memset(xfer, 0, sizeof(xfer)); + xfer[0].bits_per_word = 8; + xfer[0].speed_hz = SPI_SPEED; + xfer[1].bits_per_word = 8; + xfer[1].speed_hz = SPI_SPEED; + + memset(&recv_buffer, 0, sizeof(recv_buffer)); + memset(&data_buffer, 0, sizeof(data_buffer)); + + data_buffer[1] = addr << 4 | 1 << 3; + xfer[0].tx_buf = (unsigned long)data_buffer; + xfer[0].len = 2; + + xfer[1].rx_buf = (unsigned long)recv_buffer; + xfer[1].len = 4; + res = ioctl(d_fd, SPI_IOC_MESSAGE(2), xfer); + if (res < 0) + { + std::cout << "Error sending SPI message\n"; + return res; + } + + // the register data is received in the reverse order + uint32_t tmp_result = 0; + for (uint32_t k = 0; k < 4; ++k) + { + tmp_result = tmp_result + ((recv_buffer[3 - k]) << 8 * k); + } + *copy_to = tmp_result; + + return 0; +} + +int Fpga_spidev::SPI_close() const +{ + return close(d_fd); +} diff --git a/src/algorithms/signal_source/libs/fpga_spidev.h b/src/algorithms/signal_source/libs/fpga_spidev.h new file mode 100644 index 000000000..5fbe2f41c --- /dev/null +++ b/src/algorithms/signal_source/libs/fpga_spidev.h @@ -0,0 +1,61 @@ +/*! + * \file fpga_spidev.h + * \brief FPGA SPI control. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_FPGA_SPIDEV_H +#define GNSS_SDR_FPGA_SPIDEV_H + +#include + +class Fpga_spidev +{ +public: + /*! + * \brief Default constructor. + */ + Fpga_spidev() = default; + + /*! + * \brief Default destructor. + */ + ~Fpga_spidev() = default; + + /*! + * \brief write a register through the SPI. + */ + int write_reg32(char addr, uint32_t data); + + /*! + * \brief read a register through the SPI. + */ + int read_reg32(uint8_t addr, uint32_t* copy_to); + /*! + * \brief Open the SPI device driver. + */ + int SPI_open(void); + + /*! + * \brief Close the SPI device driver + */ + int SPI_close(void) const; + +private: + static const uint32_t SPI_SPEED = 250000; + const std::string SPI_DEVICE_NAME = std::string("/dev/spidev2.0"); // Switch UIO device name + + int d_fd; +}; + + +#endif // GNSS_SDR_FPGA_SPIDEV_H diff --git a/src/algorithms/signal_source/libs/fpga_switch.cc b/src/algorithms/signal_source/libs/fpga_switch.cc index f2d51c2fb..2730bdf36 100644 --- a/src/algorithms/signal_source/libs/fpga_switch.cc +++ b/src/algorithms/signal_source/libs/fpga_switch.cc @@ -21,6 +21,7 @@ */ #include "fpga_switch.h" +#include "uio_fpga.h" #include // for open, O_RDWR, O_SYNC #include // for cout #include // for mmap @@ -32,11 +33,19 @@ #include #endif -Fpga_Switch::Fpga_Switch(const std::string &device_name) +Fpga_Switch::Fpga_Switch(void) { - if ((d_device_descriptor = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1) + std::string device_io_name; // Switch UIO device file + // find the uio device file corresponding to the switch. + if (find_uio_dev_file_name(device_io_name, SWITCH_DEVICE_NAME, 0) < 0) { - LOG(WARNING) << "Cannot open deviceio" << device_name; + std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << SWITCH_DEVICE_NAME << '\n'; + return; + } + + if ((d_device_descriptor = open(device_io_name.c_str(), O_RDWR | O_SYNC)) == -1) + { + LOG(WARNING) << "Cannot open deviceio" << device_io_name; } d_map_base = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0)); diff --git a/src/algorithms/signal_source/libs/fpga_switch.h b/src/algorithms/signal_source/libs/fpga_switch.h index b4a73cb4f..8a46c214d 100644 --- a/src/algorithms/signal_source/libs/fpga_switch.h +++ b/src/algorithms/signal_source/libs/fpga_switch.h @@ -42,8 +42,7 @@ public: /*! * \brief Constructor */ - explicit Fpga_Switch(const std::string& device_name); - + Fpga_Switch(void); /*! * \brief Destructor */ @@ -55,6 +54,7 @@ public: void set_switch_position(int32_t switch_position); private: + const std::string SWITCH_DEVICE_NAME = std::string("AXIS_Switch_v1_0_0"); // Switch UIO device name static const size_t FPGA_PAGE_SIZE = 0x1000; static const uint32_t TEST_REGISTER_TRACK_WRITEVAL = 0x55AA; static const uint32_t MAX_LENGTH_DEVICEIO_NAME = 50; diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h index 722440f32..8de75e087 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h @@ -65,11 +65,11 @@ public: } /*! - * \brief Returns "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga" + * \brief Returns "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA" */ inline std::string implementation() override { - return "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"; + return "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA"; } /*! diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h index 510df45ea..1b3c8f52b 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h @@ -59,11 +59,11 @@ public: } /*! - * \brief Returns "Galileo_E5a_DLL_PLL_Tracking_Fpga" + * \brief Returns "Galileo_E5a_DLL_PLL_Tracking_FPGA" */ inline std::string implementation() override { - return "Galileo_E5a_DLL_PLL_Tracking_Fpga"; + return "Galileo_E5a_DLL_PLL_Tracking_FPGA"; } /*! diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h index dedefd7c5..ed3b23f4a 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h @@ -64,11 +64,11 @@ public: } /*! - * \brief Returns "GPS_L1_CA_DLL_PLL_Tracking_Fpga" + * \brief Returns "GPS_L1_CA_DLL_PLL_Tracking_FPGA" */ inline std::string implementation() override { - return "GPS_L1_CA_DLL_PLL_Tracking_Fpga"; + return "GPS_L1_CA_DLL_PLL_Tracking_FPGA"; } /*! diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h index 506e8fec6..a89dd5d55 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h @@ -57,10 +57,10 @@ public: return role_; } - //! Returns "GPS_L2_M_DLL_PLL_Tracking_Fpga" + //! Returns "GPS_L2_M_DLL_PLL_Tracking_FPGA" inline std::string implementation() override { - return "GPS_L2_M_DLL_PLL_Tracking_Fpga"; + return "GPS_L2_M_DLL_PLL_Tracking_FPGA"; } inline size_t item_size() override diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h index 24fc37a14..ed85735b2 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h @@ -65,11 +65,11 @@ public: } /*! - * \brief Returns "GPS_L5_DLL_PLL_Tracking_Fpga" + * \brief Returns "GPS_L5_DLL_PLL_Tracking_FPGA" */ inline std::string implementation() override { - return "GPS_L5_DLL_PLL_Tracking_Fpga"; + return "GPS_L5_DLL_PLL_Tracking_FPGA"; } /*! diff --git a/src/core/monitor/gnss_synchro_monitor.cc b/src/core/monitor/gnss_synchro_monitor.cc index 502a5ed48..98526fe60 100644 --- a/src/core/monitor/gnss_synchro_monitor.cc +++ b/src/core/monitor/gnss_synchro_monitor.cc @@ -46,6 +46,7 @@ gnss_synchro_monitor::gnss_synchro_monitor(int n_channels, : gr::block("gnss_synchro_monitor", gr::io_signature::make(n_channels, n_channels, sizeof(Gnss_Synchro)), gr::io_signature::make(0, 0, 0)), + count(0), d_nchannels(n_channels), d_decimation_factor(decimation_factor) { @@ -73,7 +74,6 @@ int gnss_synchro_monitor::general_work(int noutput_items __attribute__((unused)) for (int channel_index = 0; channel_index < d_nchannels; channel_index++) { // Loop through each item in each input stream channel - int count = 0; for (int item_index = 0; item_index < ninput_items[channel_index]; item_index++) { // Use the count variable to limit how many items are sent per channel diff --git a/src/core/monitor/gnss_synchro_monitor.h b/src/core/monitor/gnss_synchro_monitor.h index b45b7cc5b..64749a001 100644 --- a/src/core/monitor/gnss_synchro_monitor.h +++ b/src/core/monitor/gnss_synchro_monitor.h @@ -71,9 +71,10 @@ private: const std::vector& udp_addresses, bool enable_protobuf); + std::unique_ptr udp_sink_ptr; + int count; int d_nchannels; int d_decimation_factor; - std::unique_ptr udp_sink_ptr; }; diff --git a/src/core/receiver/CMakeLists.txt b/src/core/receiver/CMakeLists.txt index 0dfc09a84..cacef7f6f 100644 --- a/src/core/receiver/CMakeLists.txt +++ b/src/core/receiver/CMakeLists.txt @@ -98,6 +98,14 @@ if(ENABLE_AD9361) target_compile_definitions(core_receiver PRIVATE -DAD9361_DRIVER=1) endif() +if(ENABLE_MAX2771) + target_compile_definitions(core_receiver PRIVATE -DMAX2771_DRIVER=1) +endif() + +if(ENABLE_DMA_PROXY) + target_compile_definitions(core_receiver PRIVATE -DDMA_PROXY_DRIVER=1) +endif() + if(ENABLE_OSMOSDR) if(GROSMOSDR_FOUND) target_compile_definitions(core_receiver PRIVATE -DOSMOSDR_DRIVER=1) diff --git a/src/core/receiver/concurrent_map.h b/src/core/receiver/concurrent_map.h index 330ab02ef..d16a963d7 100644 --- a/src/core/receiver/concurrent_map.h +++ b/src/core/receiver/concurrent_map.h @@ -36,52 +36,48 @@ template */ class Concurrent_Map { - typedef typename std::map::iterator Data_iterator; // iterator is scope dependent public: void write(int key, Data const& data) { - std::unique_lock lock(the_mutex); - Data_iterator data_iter; - data_iter = the_map.find(key); + std::lock_guard lock(the_mutex); + auto data_iter = the_map.find(key); if (data_iter != the_map.end()) { data_iter->second = data; // update } else { - the_map.insert(std::pair(key, data)); // insert SILENTLY fails if the item already exists in the map! + the_map.insert(std::pair(key, data)); // insert does not overwrite if the item already exists in the map! } - lock.unlock(); } - std::map get_map_copy() + std::map get_map_copy() const& { - std::unique_lock lock(the_mutex); - std::map map_aux = the_map; - lock.unlock(); - return map_aux; + std::lock_guard lock(the_mutex); + return the_map; // This implicitly creates a copy } - size_t size() + std::map get_map_copy() && { - std::unique_lock lock(the_mutex); - size_t size_ = the_map.size(); - lock.unlock(); - return size_; + std::lock_guard lock(the_mutex); + return std::move(the_map); } - bool read(int key, Data& p_data) + size_t size() const { - std::unique_lock lock(the_mutex); - Data_iterator data_iter; - data_iter = the_map.find(key); + std::lock_guard lock(the_mutex); + return the_map.size(); + } + + bool read(int key, Data& p_data) const + { + std::lock_guard lock(the_mutex); + auto data_iter = the_map.find(key); if (data_iter != the_map.end()) { p_data = data_iter->second; - lock.unlock(); return true; } - lock.unlock(); return false; } diff --git a/src/core/receiver/concurrent_queue.h b/src/core/receiver/concurrent_queue.h index ac7be0f17..ed4e68b0a 100644 --- a/src/core/receiver/concurrent_queue.h +++ b/src/core/receiver/concurrent_queue.h @@ -19,9 +19,10 @@ #include #include +#include #include #include -#include +#include /** \addtogroup Core * \{ */ @@ -33,48 +34,53 @@ template /*! * \brief This class implements a thread-safe std::queue - * - * Thread-safe object queue which uses the library - * boost_thread to perform MUTEX based on the code available at - * https://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html */ class Concurrent_Queue { public: - void push(Data const& data) + void push(const Data& data) { - std::unique_lock lock(the_mutex); - the_queue.push(data); - lock.unlock(); + { + std::lock_guard lock(the_mutex); + the_queue.push(data); + } the_condition_variable.notify_one(); } - bool empty() const + void push(Data&& data) { - std::unique_lock lock(the_mutex); - return the_queue.empty(); + { + std::lock_guard lock(the_mutex); + the_queue.push(std::move(data)); + } + the_condition_variable.notify_one(); } - size_t size() const + bool empty() const noexcept { - std::unique_lock lock(the_mutex); + return size() == 0; + } + + size_t size() const noexcept + { + std::lock_guard lock(the_mutex); return the_queue.size(); } void clear() { - std::unique_lock lock(the_mutex); - the_queue = std::queue(); + std::lock_guard lock(the_mutex); + std::queue().swap(the_queue); } bool try_pop(Data& popped_value) { - std::unique_lock lock(the_mutex); + std::lock_guard lock(the_mutex); if (the_queue.empty()) { return false; } - popped_value = the_queue.front(); + popped_value = std::move(the_queue.front()); the_queue.pop(); return true; } @@ -82,26 +88,21 @@ public: void wait_and_pop(Data& popped_value) { std::unique_lock lock(the_mutex); - while (the_queue.empty()) - { - the_condition_variable.wait(lock); - } - popped_value = the_queue.front(); + the_condition_variable.wait(lock, [this] { return !the_queue.empty(); }); + popped_value = std::move(the_queue.front()); the_queue.pop(); } bool timed_wait_and_pop(Data& popped_value, int wait_ms) { std::unique_lock lock(the_mutex); - if (the_queue.empty()) + if (!the_condition_variable.wait_for(lock, + std::chrono::milliseconds(wait_ms), + [this] { return !the_queue.empty(); })) { - the_condition_variable.wait_for(lock, std::chrono::milliseconds(wait_ms)); - if (the_queue.empty()) - { - return false; - } + return false; } - popped_value = the_queue.front(); + popped_value = std::move(the_queue.front()); the_queue.pop(); return true; } diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 1a48e0a7f..ce77442ee 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -113,6 +113,7 @@ #include "tracking_interface.h" #include "two_bit_cpx_file_signal_source.h" #include "two_bit_packed_file_signal_source.h" +#include // for exit #include // for exception #include // for cerr #include // for move @@ -166,8 +167,17 @@ #include "fmcomms2_signal_source.h" #endif -#if AD9361_DRIVER -#include "ad9361_fpga_signal_source.h" +#if ENABLE_FPGA and AD9361_DRIVER +#include "adrv9361_z7035_signal_source_fpga.h" +#include "fmcomms5_signal_source_fpga.h" +#endif + +#if MAX2771_DRIVER +#include "max2771_evkit_signal_source_fpga.h" +#endif + +#if DMA_PROXY_DRIVER +#include "dma_signal_source_fpga.h" #endif #if LIMESDR_DRIVER @@ -811,12 +821,34 @@ std::unique_ptr GNSSBlockFactory::GetBlock( } #endif -#if AD9361_DRIVER - // The AD9361_DRIVER Driver must be instantiated last. In this way, when using the FPGA, and when using the GNSS receiver - // in post-processing mode, the receiver is configured and ready when the DMA starts sending samples to the receiver. - else if (implementation == "Ad9361_Fpga_Signal_Source") +#if ENABLE_FPGA and AD9361_DRIVER + else if (implementation == "ADRV9361_Z7035_Signal_Source_FPGA") { - std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams, queue); + block = std::move(block_); + } + else if (implementation == "FMCOMMS5_Signal_Source_FPGA") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams, queue); + block = std::move(block_); + } +#endif + +#if ENABLE_FPGA and MAX2771_DRIVER + else if (implementation == "MAX2771_EVKIT_Signal_Source_FPGA") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams, queue); + block = std::move(block_); + } +#endif + +#if ENABLE_FPGA and DMA_PROXY_DRIVER + else if (implementation == "DMA_Signal_Source_FPGA") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams, queue); block = std::move(block_); } @@ -1053,31 +1085,31 @@ std::unique_ptr GNSSBlockFactory::GetBlock( } #endif #if ENABLE_FPGA - else if (implementation == "GPS_L1_CA_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L1_CA_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga") + else if (implementation == "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L2_M_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L2_M_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L5i_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L5i_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E5a_Pcps_Acquisition_Fpga") + else if (implementation == "Galileo_E5a_Pcps_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); @@ -1203,31 +1235,31 @@ std::unique_ptr GNSSBlockFactory::GetBlock( } #endif #if ENABLE_FPGA - else if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L2_M_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L2_M_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if ((implementation == "GPS_L5i_DLL_PLL_Tracking_Fpga") or (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga")) + else if ((implementation == "GPS_L5i_DLL_PLL_Tracking_FPGA") or (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA")) { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); @@ -1491,31 +1523,31 @@ std::unique_ptr GNSSBlockFactory::GetAcqBlock( } #endif #if ENABLE_FPGA - else if (implementation == "GPS_L1_CA_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L1_CA_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga") + else if (implementation == "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L2_M_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L2_M_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L5i_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L5i_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E5a_Pcps_Acquisition_Fpga") + else if (implementation == "Galileo_E5a_Pcps_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); @@ -1659,31 +1691,31 @@ std::unique_ptr GNSSBlockFactory::GetTrkBlock( } #endif #if ENABLE_FPGA - else if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L2_M_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L2_M_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if ((implementation == "GPS_L5i_DLL_PLL_Tracking_Fpga") or (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga")) + else if ((implementation == "GPS_L5i_DLL_PLL_Tracking_FPGA") or (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA")) { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index 957077eca..c7cbb9f07 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -48,6 +48,7 @@ #include // for transform, sort, unique #include // for floor #include // for size_t +#include // for exit #include // for exception #include // for operator<< #include // for insert_iterator, inserter @@ -124,9 +125,9 @@ void GNSSFlowgraph::init() sources_count_ = configuration_->property("GNSS-SDR.num_sources", sources_count_deprecated); // Avoid segmentation fault caused by wrong configuration - if (sources_count_ == 2 && block_factory->GetSignalSource(configuration_.get(), queue_.get(), 0)->implementation() == "Multichannel_File_Signal_Source") + if (sources_count_ == 2 && configuration_->property("SignalSource.implementation", std::string("")) == "Multichannel_File_Signal_Source") { - std::cout << " * Please set GNSS-SDR.num_sources=1 in your configuraiion file\n"; + std::cout << " * Please set GNSS-SDR.num_sources=1 in your configuration file\n"; std::cout << " if you are using the Multichannel_File_Signal_Source implementation.\n"; sources_count_ = 1; } @@ -136,7 +137,13 @@ void GNSSFlowgraph::init() for (int i = 0; i < sources_count_; i++) { DLOG(INFO) << "Creating source " << i; - sig_source_.push_back(block_factory->GetSignalSource(configuration_.get(), queue_.get(), i)); + auto check_not_nullptr = block_factory->GetSignalSource(configuration_.get(), queue_.get(), i); + if (!check_not_nullptr) + { + std::cout << "GNSS-SDR program ended.\n"; + exit(1); + } + sig_source_.push_back(std::move(check_not_nullptr)); if (enable_fpga_offloading_ == false) { auto& src = sig_source_.back(); @@ -547,7 +554,7 @@ int GNSSFlowgraph::connect_fpga_flowgraph() if (src == nullptr) { help_hint_ += " * Check implementation name for SignalSource block.\n"; - help_hint_ += " Signal Source block implementation for FPGA off-loading should be Ad9361_Fpga_Signal_Source\n"; + help_hint_ += " Signal Source block implementation for FPGA off-loading should be Ad9361_Signal_Source_Fpga or Fpga_DMA_2Signal_Source\n"; return 1; } if (src->item_size() == 0) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc index 816dbfe1a..4d68363f8 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc @@ -67,7 +67,7 @@ class GalileoE1PcpsAmbiguousAcquisitionTestFpga : public ::testing::Test { public: bool acquire_signal(); - std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_Fpga"; + std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_FPGA"; std::vector gnss_synchro_vec; const int32_t TEST_ACQ_SKIP_SAMPLES = 1024; @@ -321,7 +321,7 @@ bool GalileoE1PcpsAmbiguousAcquisitionTestFpga::acquire_signal() // instantiate the FPGA switch and set the // switch position to DMA. std::shared_ptr switch_fpga; - switch_fpga = std::make_shared("/dev/uio1"); + switch_fpga = std::make_shared(); switch_fpga->set_switch_position(0); // set switch position to DMA // create the correspondign acquisition block according to the desired tracking signal @@ -397,7 +397,7 @@ bool GalileoE1PcpsAmbiguousAcquisitionTestFpga::acquire_signal() void GalileoE1PcpsAmbiguousAcquisitionTestFpga::init() { config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga"); + config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA"); config->set_property("Acquisition.threshold", "0.00001"); config->set_property("Acquisition.doppler_max", std::to_string(doppler_max)); config->set_property("Acquisition.doppler_step", std::to_string(doppler_step)); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc index ee06f57ce..47ddc54aa 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc @@ -66,7 +66,7 @@ class GpsL1CaPcpsAcquisitionTestFpga : public ::testing::Test { public: bool acquire_signal(); - std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_Fpga"; + std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_FPGA"; std::vector gnss_synchro_vec; const int32_t TEST_ACQ_SKIP_SAMPLES = 1024; @@ -320,7 +320,7 @@ bool GpsL1CaPcpsAcquisitionTestFpga::acquire_signal() // instantiate the FPGA switch and set the // switch position to DMA. std::shared_ptr switch_fpga; - switch_fpga = std::make_shared("/dev/uio1"); + switch_fpga = std::make_shared(); switch_fpga->set_switch_position(0); // set switch position to DMA // create the correspondign acquisition block according to the desired tracking signal @@ -396,7 +396,7 @@ bool GpsL1CaPcpsAcquisitionTestFpga::acquire_signal() void GpsL1CaPcpsAcquisitionTestFpga::init() { config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_Acquisition_Fpga"); + config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_Acquisition_FPGA"); config->set_property("Acquisition.threshold", "0.00001"); config->set_property("Acquisition.doppler_max", std::to_string(doppler_max)); config->set_property("Acquisition.doppler_step", std::to_string(doppler_step)); diff --git a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc index 9824e1d17..c466a277b 100644 --- a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc @@ -638,11 +638,11 @@ bool HybridObservablesTestFpga::acquire_signal() // instantiate the FPGA switch and set the // switch position to DMA. std::shared_ptr switch_fpga; - switch_fpga = std::make_shared("/dev/uio1"); + switch_fpga = std::make_shared(); switch_fpga->set_switch_position(0); // set switch position to DMA // create the correspondign acquisition block according to the desired tracking signal - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'G'; signal = "1C"; @@ -654,7 +654,7 @@ bool HybridObservablesTestFpga::acquire_signal() args.freq_band = 0; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { tmp_gnss_synchro.System = 'E'; signal = "1B"; @@ -666,7 +666,7 @@ bool HybridObservablesTestFpga::acquire_signal() args.freq_band = 0; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'E'; signal = "5X"; @@ -678,7 +678,7 @@ bool HybridObservablesTestFpga::acquire_signal() args.freq_band = 1; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'G'; signal = "L5"; @@ -732,19 +732,19 @@ bool HybridObservablesTestFpga::acquire_signal() // number of samples that the DMA has to transfer unsigned int nsamples_to_transfer; - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS))); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E1_CODE_CHIP_RATE_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS))); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E5A_CODE_CHIP_RATE_CPS / GALILEO_E5A_CODE_LENGTH_CHIPS))); } - else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) + else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_FPGA") == 0)) { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L5I_CODE_RATE_CPS / GPS_L5I_CODE_LENGTH_CHIPS))); } @@ -762,7 +762,7 @@ bool HybridObservablesTestFpga::acquire_signal() acquisition->init(); acquisition->set_local_code(); - if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga")) + if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA")) { // Skip the first TEST_OBS_SKIP_SAMPLES samples args.skip_used_samples = 0; @@ -910,7 +910,7 @@ void HybridObservablesTestFpga::configure_receiver( config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); std::string System_and_Signal; - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { gnss_synchro_master.System = 'G'; std::string signal = "1C"; @@ -923,7 +923,7 @@ void HybridObservablesTestFpga::configure_receiver( config->set_property("TelemetryDecoder.implementation", "GPS_L1_CA_Telemetry_Decoder"); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { gnss_synchro_master.System = 'E'; std::string signal = "1B"; @@ -939,7 +939,7 @@ void HybridObservablesTestFpga::configure_receiver( config->set_property("TelemetryDecoder.implementation", "Galileo_E1B_Telemetry_Decoder"); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") // or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") // or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) { gnss_synchro_master.System = 'E'; std::string signal = "5X"; @@ -953,7 +953,7 @@ void HybridObservablesTestFpga::configure_receiver( config->set_property("TelemetryDecoder.implementation", "Galileo_E5a_Telemetry_Decoder"); } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { gnss_synchro_master.System = 'G'; std::string signal = "L5"; @@ -2031,22 +2031,22 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) args.scaling_factor = DMA_SIGNAL_SCALING_FACTOR; // reset the HW to clear the sample counters: the acquisition constructor generates a reset - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 0; } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 0; } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 1; } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 1; diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc index 4bd43fc30..d5f2348af 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc @@ -355,7 +355,7 @@ void GpsL1CADllPllTrackingTestFpga::configure_receiver() std::to_string(baseband_sampling_freq)); // Set Tracking config->set_property("Tracking_1C.implementation", - "GPS_L1_CA_DLL_PLL_Tracking_Fpga"); + "GPS_L1_CA_DLL_PLL_Tracking_FPGA"); config->set_property("Tracking_1C.item_type", "cshort"); config->set_property("Tracking_1C.dump", "true"); config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc index 39f87bdfa..a2f27204e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc @@ -536,7 +536,7 @@ void TrackingPullInTestFpga::configure_receiver( config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); std::string System_and_Signal; - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { gnss_synchro.System = 'G'; std::string signal = "1C"; @@ -545,7 +545,7 @@ void TrackingPullInTestFpga::configure_receiver( config->set_property("Tracking.early_late_space_chips", "0.5"); config->set_property("Tracking.early_late_space_narrow_chips", "0.5"); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { gnss_synchro.System = 'E'; std::string signal = "1B"; @@ -557,7 +557,7 @@ void TrackingPullInTestFpga::configure_receiver( config->set_property("Tracking.very_early_late_space_narrow_chips", "0.6"); config->set_property("Tracking.track_pilot", "true"); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga" or implementation == "Galileo_E5a_DLL_PLL_Tracking_b_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA" or implementation == "Galileo_E5a_DLL_PLL_Tracking_b_Fpga") { gnss_synchro.System = 'E'; std::string signal = "5X"; @@ -565,13 +565,13 @@ void TrackingPullInTestFpga::configure_receiver( signal.copy(gnss_synchro.Signal, 2, 0); if (implementation == "Galileo_E5a_DLL_PLL_Tracking_b") { - config->supersede_property("Tracking.implementation", std::string("Galileo_E5a_DLL_PLL_Tracking_Fpga")); + config->supersede_property("Tracking.implementation", std::string("Galileo_E5a_DLL_PLL_Tracking_FPGA")); } config->set_property("Tracking.early_late_space_chips", "0.5"); config->set_property("Tracking.track_pilot", "true"); config->set_property("Tracking.order", "2"); } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { gnss_synchro.System = 'G'; std::string signal = "L5"; @@ -634,11 +634,11 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) // instantiate the FPGA switch and set the // switch position to DMA. std::shared_ptr switch_fpga; - switch_fpga = std::make_shared("/dev/uio1"); + switch_fpga = std::make_shared(); switch_fpga->set_switch_position(0); // set switch position to DMA // create the correspondign acquisition block according to the desired tracking signal - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'G'; signal = "1C"; @@ -650,7 +650,7 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) args.freq_band = 0; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { tmp_gnss_synchro.System = 'E'; signal = "1B"; @@ -662,7 +662,7 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) args.freq_band = 0; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'E'; signal = "5X"; @@ -674,7 +674,7 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) args.freq_band = 1; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'G'; signal = "L5"; @@ -732,19 +732,19 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) // number of samples that the DMA has to transfer unsigned int nsamples_to_transfer; - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS))); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E1_CODE_CHIP_RATE_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS))); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E5A_CODE_CHIP_RATE_CPS / GALILEO_E5A_CODE_LENGTH_CHIPS))); } - else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) + else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_FPGA") == 0)) { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L5I_CODE_RATE_CPS / GPS_L5I_CODE_LENGTH_CHIPS))); } @@ -762,7 +762,7 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) acquisition->init(); acquisition->set_local_code(); - if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga")) + if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA")) { // Configure the DMA to send TEST_TRK_PULL_IN_TEST_SKIP_SAMPLES in order to initialize the internal // states of the downsampling filter in the FPGA @@ -1079,22 +1079,22 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) std::shared_ptr acquisition; // reset the HW to clear the sample counters: the acquisition constructor generates a reset - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 0; } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 0; } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 1; } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 1;