1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-08-31 01:47:59 +00:00

Merge branch 'next' into vtl

This commit is contained in:
kalmancito
2024-08-14 15:59:28 +02:00
68 changed files with 2984 additions and 1676 deletions

View File

@@ -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

7
.gitignore vendored
View File

@@ -20,3 +20,10 @@ cmake-build-debug/
.vscode/
.vs/
Testing/
GSDR*
PVT_*
HAS_*
gnss_sdr_pvt.nmea
build-debug/
build-release/

View File

@@ -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.")

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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}
)

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
)

View File

@@ -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/
)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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"
)

View File

@@ -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}

View File

@@ -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()

View File

@@ -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.

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
)

View File

@@ -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:

View File

@@ -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<uint32_t>(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;

View File

@@ -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";
}
/*!

View File

@@ -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";
}
/*!

View File

@@ -65,7 +65,7 @@ public:
}
/*!
* \brief Returns "Galileo_E5b_Pcps_Acquisition_Fpga"
* \brief Returns "Galileo_E5b_Pcps_Acquisition_FPGA"
*/
inline std::string implementation() override
{

View File

@@ -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";
}
/*!

View File

@@ -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

View File

@@ -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";
}
/*!

View File

@@ -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)

View File

@@ -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 <ul>
* <li> Javier Arribas, jarribas(at)cttc.es
* <li> Marc Majoral, mmajoral(at)cttc.es
* </ul>
*
* -----------------------------------------------------------------------------
*
* 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 <iio.h>
#include <algorithm> // for std::max
#include <chrono> // for std::chrono
#include <cmath> // for std::floor
#include <exception> // for std::exception
#include <fcntl.h> // for open, O_WRONLY
#include <fstream> // for std::ifstream
#include <iomanip> // for std::setprecision
#include <iostream> // for std::cout
#include <unistd.h> // for write
#include <vector> // fr std::vector
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h>
#else
#include <absl/log/check.h>
#include <absl/log/log.h>
#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<pmt::pmt_t> *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<uint64_t>(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<int64_t>(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<uint64_t>(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_))),
tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast<uint64_t>(500000))),
Fpass_(configuration->property(role + ".Fpass", static_cast<float>(0.0))),
Fstop_(configuration->property(role + ".Fstop", static_cast<float>(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<uint64_t>(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<uint64_t>(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<Fpga_Switch>(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<double>(size) / static_cast<double>(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<double>(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<uint64_t>(size) - bytes_to_skip;
samples_ = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size_) - ceil(0.002 * static_cast<double>(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<double>(size) / static_cast<double>(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<double>(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<uint64_t>(size) - bytes_to_skip;
samples_rx2 = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size_) - ceil(0.002 * static_cast<double>(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<double>(samples_) * (1 / static_cast<double>(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<uint64_t>(std::floor(static_cast<float>(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<float>(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<Fpga_buffer_monitor>(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<Fpga_dynamic_bit_selection>(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<std::mutex> 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<std::mutex> 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<std::mutex> lock(dynamic_bit_selection_mutex);
bool bit_selection_enabled = enable_dynamic_bit_selection_;
lock.unlock();
if (bit_selection_enabled == true)
{
std::unique_lock<std::mutex> 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<pmt::pmt_t> *queue)
{
std::ifstream infile1;
infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit);
// FPGA DMA control
dma_fpga = std::make_shared<Fpga_DMA>();
// 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<int8_t> 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<char *>(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<char *>(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<std::mutex> 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<std::mutex> 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<std::mutex> 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 {};
}

View File

@@ -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 <ul>
* <li> Javier Arribas, jarribas(at)cttc.es
* <li> Marc Majoral, mmajoral(at)cttc.es
* </ul>
*
* -----------------------------------------------------------------------------
*
* 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 <algorithm> // for std::max
#include <chrono> // for std::chrono
#include <cmath> // for std::floor
#include <exception> // for std::exception
#include <iostream> // for std::cout
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h>
#else
#include <absl/log/check.h>
#include <absl/log/log.h>
#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<pmt::pmt_t> *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<uint64_t>(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<uint64_t>(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_))),
tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast<uint64_t>(500000))),
Fpass_(configuration->property(role + ".Fpass", static_cast<float>(0.0))),
Fstop_(configuration->property(role + ".Fstop", static_cast<float>(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<uint64_t>(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<Fpga_Switch>();
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<uint64_t>(std::floor(static_cast<float>(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<float>(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<Fpga_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<Fpga_dynamic_bit_selection>(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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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 {};
}

View File

@@ -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<pmt::pmt_t> *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<pmt::pmt_t> *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<Fpga_Switch> switch_fpga;
std::shared_ptr<Fpga_dynamic_bit_selection> dynamic_bit_selection_fpga;
std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga;
std::shared_ptr<Fpga_DMA> dma_fpga;
std::mutex dma_mutex;
std::mutex dynamic_bit_selection_mutex;
std::mutex buffer_monitor_mutex;
Concurrent_Queue<pmt::pmt_t> *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

View File

@@ -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 <algorithm> // for std::min
#include <chrono> // for std::chrono
#include <fcntl.h> // for open, O_WRONLY
#include <fstream> // for std::ifstream
#include <iomanip> // for std::setprecision
#include <iostream> // for std::cout
#include <vector> // fr std::vector
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h>
#else
#include <absl/log/check.h>
#include <absl/log/log.h>
#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<pmt::pmt_t> *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<int64_t>(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<uint64_t>(seconds_to_skip * sample_rate_) * 2;
}
if (header_size > 0)
{
samples_to_skip_ += header_size;
}
switch_fpga = std::make_shared<Fpga_Switch>();
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<double>(size) / static_cast<double>(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<double>(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<uint64_t>(size) - bytes_to_skip;
samples_ = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size_) - ceil(0.002 * static_cast<double>(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<double>(size) / static_cast<double>(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<double>(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<uint64_t>(size) - bytes_to_skip;
samples_rx2 = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size_) - ceil(0.002 * static_cast<double>(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<double>(samples_) * (1 / static_cast<double>(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<Fpga_dynamic_bit_selection>(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<std::mutex> 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<std::mutex> 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<std::mutex> 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<pmt::pmt_t> *queue)
{
std::ifstream infile1;
infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit);
// FPGA DMA control
dma_fpga = std::make_shared<Fpga_DMA>();
// 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<int8_t> 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<char *>(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<char *>(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<std::mutex> 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<std::mutex> 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 {};
}

View File

@@ -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 <pmt/pmt.h>
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
/** \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<pmt::pmt_t> *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<pmt::pmt_t> *queue);
void run_dynamic_bit_selection_process();
std::thread thread_file_to_dma;
std::thread thread_dynamic_bit_selection;
std::shared_ptr<Fpga_Switch> switch_fpga;
std::shared_ptr<Fpga_dynamic_bit_selection> dynamic_bit_selection_fpga;
std::shared_ptr<Fpga_DMA> dma_fpga;
std::mutex dma_mutex;
std::mutex dynamic_bit_selection_mutex;
Concurrent_Queue<pmt::pmt_t> *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

View File

@@ -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 <ul>
* <li> Javier Arribas, jarribas(at)cttc.es
* <li> Marc Majoral, mmajoral(at)cttc.es
* </ul>
*
* -----------------------------------------------------------------------------
*
* 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 <algorithm> // for std::max
#include <chrono> // for std::chrono
#include <cmath> // for std::floor
#include <exception> // for std::exception
#include <iostream> // for std::cout
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h>
#else
#include <absl/log/check.h>
#include <absl/log/log.h>
#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<pmt::pmt_t> *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<uint64_t>(GPS_L1_FREQ_HZ))),
freq1_(configuration->property(role + ".freq1", static_cast<uint64_t>(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<float>(0.0))),
Fstop_(configuration->property(role + ".Fstop", static_cast<float>(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<Fpga_Switch>();
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<Fpga_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<Fpga_dynamic_bit_selection>(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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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 {};
}

View File

@@ -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 <pmt/pmt.h>
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
/** \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<pmt::pmt_t> *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<Fpga_Switch> switch_fpga;
std::shared_ptr<Fpga_dynamic_bit_selection> dynamic_bit_selection_fpga;
std::shared_ptr<Fpga_buffer_monitor> 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

View File

@@ -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 <algorithm> // for std::max
#include <chrono> // for std::chrono
#include <cmath> // for std::floor
#include <exception> // for std::exception
#include <iostream> // for std::cout
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h>
#else
#include <absl/log/check.h>
#include <absl/log/log.h>
#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<pmt::pmt_t> *queue __attribute__((unused)))
: SignalSourceBase(configuration, role, "MAX2771_EVKIT_Signal_Source_FPGA"s),
freq_(configuration->property(role + ".freq", static_cast<uint64_t>(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<uint32_t> register_values = setup_regs();
spidev_fpga = std::make_shared<Fpga_spidev>();
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<Fpga_buffer_monitor>(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<uint32_t> MAX2771EVKITSignalSourceFPGA::setup_regs(void)
{
std::vector<uint32_t> register_values = std::vector<uint32_t>(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<uint64_t>(GPS_L1_FREQ_HZ):
freq_sel = 0x604;
break;
case static_cast<uint64_t>(GPS_L2_FREQ_HZ):
freq_sel = 0x4B0;
break;
case static_cast<uint64_t>(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<uint32_t> 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<uint32_t> reg_read = std::vector<uint32_t>(register_values.size());
for (uint8_t n = 0; n < register_values.size(); ++n)
{
status = spidev_fpga->read_reg32(n, &reg_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<uint32_t> 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<std::mutex> 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<std::mutex> 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 {};
}

View File

@@ -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 <pmt/pmt.h> // for pmt::pmt_t
#include <cstdint> // for fixed-width integer types
#include <memory> // for smart pointers
#include <mutex> // for mutex
#include <string> // for strings
#include <thread> // for threads
#include <vector> // 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<pmt::pmt_t> *queue);
~MAX2771EVKITSignalSourceFPGA();
std::vector<uint32_t> 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<uint32_t> register_values);
void run_buffer_monitor_process();
std::thread thread_buffer_monitor;
std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga;
std::shared_ptr<Fpga_spidev> 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

View File

@@ -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)

View File

@@ -13,6 +13,7 @@
* -----------------------------------------------------------------------------
*/
#include "ad936x_iio_custom.h"
#include "display.h"
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <chrono>
@@ -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<Concurrent_Queue<Gnss
GnssTime_queue = std::move(queue);
}
void ad936x_iio_custom::set_pps_samplestamp_queue(std::shared_ptr<Concurrent_Queue<PpsSamplestamp>> 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 &param, 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 &param,
}
}
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<ad936x_iio_samples> &current_buffer)
{
used_buffers.wait_and_pop(current_buffer);
}
void ad936x_iio_custom::push_sample_buffer(std::shared_ptr<ad936x_iio_samples> &current_buffer)
{
free_buffers.push(current_buffer);
}
void ad936x_iio_custom::capture(const std::vector<std::string> &channels)
{
if (check_device() == false) return;

View File

@@ -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 <ctime> // for time, localtime
#include <fcntl.h> // for open, O_RDWR, O_SYNC
#include <fstream> // 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

View File

@@ -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;

View File

@@ -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

View File

@@ -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 <cstring> // for memset()
#include <fcntl.h> // for open(), O_RDWR
#include <iostream> // for std::cerr
#include <linux/spi/spidev.h> // spidev driver
#include <sys/ioctl.h> // for ioctl()
#include <unistd.h> // 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);
}

View File

@@ -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 <string>
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

View File

@@ -21,6 +21,7 @@
*/
#include "fpga_switch.h"
#include "uio_fpga.h"
#include <fcntl.h> // for open, O_RDWR, O_SYNC
#include <iostream> // for cout
#include <sys/mman.h> // for mmap
@@ -32,11 +33,19 @@
#include <absl/log/log.h>
#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<volatile unsigned *>(mmap(nullptr, FPGA_PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0));

View File

@@ -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;

View File

@@ -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";
}
/*!

View File

@@ -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";
}
/*!

View File

@@ -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";
}
/*!

View File

@@ -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

View File

@@ -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";
}
/*!

View File

@@ -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

View File

@@ -71,9 +71,10 @@ private:
const std::vector<std::string>& udp_addresses,
bool enable_protobuf);
std::unique_ptr<Gnss_Synchro_Udp_Sink> udp_sink_ptr;
int count;
int d_nchannels;
int d_decimation_factor;
std::unique_ptr<Gnss_Synchro_Udp_Sink> udp_sink_ptr;
};

View File

@@ -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)

View File

@@ -36,52 +36,48 @@ template <typename Data>
*/
class Concurrent_Map
{
typedef typename std::map<int, Data>::iterator Data_iterator; // iterator is scope dependent
public:
void write(int key, Data const& data)
{
std::unique_lock<std::mutex> lock(the_mutex);
Data_iterator data_iter;
data_iter = the_map.find(key);
std::lock_guard<std::mutex> 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<int, Data>(key, data)); // insert SILENTLY fails if the item already exists in the map!
the_map.insert(std::pair<int, Data>(key, data)); // insert does not overwrite if the item already exists in the map!
}
lock.unlock();
}
std::map<int, Data> get_map_copy()
std::map<int, Data> get_map_copy() const&
{
std::unique_lock<std::mutex> lock(the_mutex);
std::map<int, Data> map_aux = the_map;
lock.unlock();
return map_aux;
std::lock_guard<std::mutex> lock(the_mutex);
return the_map; // This implicitly creates a copy
}
size_t size()
std::map<int, Data> get_map_copy() &&
{
std::unique_lock<std::mutex> lock(the_mutex);
size_t size_ = the_map.size();
lock.unlock();
return size_;
std::lock_guard<std::mutex> lock(the_mutex);
return std::move(the_map);
}
bool read(int key, Data& p_data)
size_t size() const
{
std::unique_lock<std::mutex> lock(the_mutex);
Data_iterator data_iter;
data_iter = the_map.find(key);
std::lock_guard<std::mutex> lock(the_mutex);
return the_map.size();
}
bool read(int key, Data& p_data) const
{
std::lock_guard<std::mutex> 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;
}

View File

@@ -19,9 +19,10 @@
#include <chrono>
#include <condition_variable>
#include <cstddef>
#include <mutex>
#include <queue>
#include <thread>
#include <utility>
/** \addtogroup Core
* \{ */
@@ -33,48 +34,53 @@ template <typename Data>
/*!
* \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<std::mutex> lock(the_mutex);
the_queue.push(data);
lock.unlock();
{
std::lock_guard<std::mutex> lock(the_mutex);
the_queue.push(data);
}
the_condition_variable.notify_one();
}
bool empty() const
void push(Data&& data)
{
std::unique_lock<std::mutex> lock(the_mutex);
return the_queue.empty();
{
std::lock_guard<std::mutex> 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<std::mutex> lock(the_mutex);
return size() == 0;
}
size_t size() const noexcept
{
std::lock_guard<std::mutex> lock(the_mutex);
return the_queue.size();
}
void clear()
{
std::unique_lock<std::mutex> lock(the_mutex);
the_queue = std::queue<Data>();
std::lock_guard<std::mutex> lock(the_mutex);
std::queue<Data>().swap(the_queue);
}
bool try_pop(Data& popped_value)
{
std::unique_lock<std::mutex> lock(the_mutex);
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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;
}

View File

@@ -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 <cstdlib> // for exit
#include <exception> // for exception
#include <iostream> // for cerr
#include <utility> // 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<GNSSBlockInterface> 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<GNSSBlockInterface> block_ = std::make_unique<Ad9361FpgaSignalSource>(configuration, role, in_streams,
std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<Adrv9361z7035SignalSourceFPGA>(configuration, role, in_streams,
out_streams, queue);
block = std::move(block_);
}
else if (implementation == "FMCOMMS5_Signal_Source_FPGA")
{
std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<Fmcomms5SignalSourceFPGA>(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<GNSSBlockInterface> block_ = std::make_unique<MAX2771EVKITSignalSourceFPGA>(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<GNSSBlockInterface> block_ = std::make_unique<DMASignalSourceFPGA>(configuration, role, in_streams,
out_streams, queue);
block = std::move(block_);
}
@@ -1053,31 +1085,31 @@ std::unique_ptr<GNSSBlockInterface> 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<GNSSBlockInterface> block_ = std::make_unique<GpsL1CaPcpsAcquisitionFpga>(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<GNSSBlockInterface> block_ = std::make_unique<GalileoE1PcpsAmbiguousAcquisitionFpga>(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<GNSSBlockInterface> block_ = std::make_unique<GpsL2MPcpsAcquisitionFpga>(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<AcquisitionInterface> block_ = std::make_unique<GpsL5iPcpsAcquisitionFpga>(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<GNSSBlockInterface> block_ = std::make_unique<GalileoE5aPcpsAcquisitionFpga>(configuration, role, in_streams,
out_streams);
@@ -1203,31 +1235,31 @@ std::unique_ptr<GNSSBlockInterface> 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<TrackingInterface> block_ = std::make_unique<GpsL1CaDllPllTrackingFpga>(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<TrackingInterface> block_ = std::make_unique<GalileoE1DllPllVemlTrackingFpga>(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<GNSSBlockInterface> block_ = std::make_unique<GpsL2MDllPllTrackingFpga>(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<GNSSBlockInterface> block_ = std::make_unique<GpsL5DllPllTrackingFpga>(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<GNSSBlockInterface> block_ = std::make_unique<GalileoE5aDllPllTrackingFpga>(configuration, role, in_streams,
out_streams);
@@ -1491,31 +1523,31 @@ std::unique_ptr<AcquisitionInterface> 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<AcquisitionInterface> block_ = std::make_unique<GpsL1CaPcpsAcquisitionFpga>(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<AcquisitionInterface> block_ = std::make_unique<GalileoE1PcpsAmbiguousAcquisitionFpga>(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<AcquisitionInterface> block_ = std::make_unique<GpsL2MPcpsAcquisitionFpga>(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<AcquisitionInterface> block_ = std::make_unique<GpsL5iPcpsAcquisitionFpga>(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<AcquisitionInterface> block_ = std::make_unique<GalileoE5aPcpsAcquisitionFpga>(configuration, role, in_streams,
out_streams);
@@ -1659,31 +1691,31 @@ std::unique_ptr<TrackingInterface> 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<TrackingInterface> block_ = std::make_unique<GpsL1CaDllPllTrackingFpga>(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<TrackingInterface> block_ = std::make_unique<GalileoE1DllPllVemlTrackingFpga>(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<TrackingInterface> block_ = std::make_unique<GpsL2MDllPllTrackingFpga>(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<TrackingInterface> block_ = std::make_unique<GpsL5DllPllTrackingFpga>(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<TrackingInterface> block_ = std::make_unique<GalileoE5aDllPllTrackingFpga>(configuration, role, in_streams,
out_streams);

View File

@@ -48,6 +48,7 @@
#include <algorithm> // for transform, sort, unique
#include <cmath> // for floor
#include <cstddef> // for size_t
#include <cstdlib> // for exit
#include <exception> // for exception
#include <iostream> // for operator<<
#include <iterator> // 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)

View File

@@ -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> 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<Fpga_Switch> switch_fpga;
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
switch_fpga = std::make_shared<Fpga_Switch>();
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));

View File

@@ -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> 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<Fpga_Switch> switch_fpga;
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
switch_fpga = std::make_shared<Fpga_Switch>();
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));

View File

@@ -638,11 +638,11 @@ bool HybridObservablesTestFpga::acquire_signal()
// instantiate the FPGA switch and set the
// switch position to DMA.
std::shared_ptr<Fpga_Switch> switch_fpga;
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
switch_fpga = std::make_shared<Fpga_Switch>();
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<unsigned int>(std::round(static_cast<double>(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<unsigned int>(std::round(static_cast<double>(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<unsigned int>(std::round(static_cast<double>(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<unsigned int>(std::round(static_cast<double>(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<GpsL1CaPcpsAcquisitionFpga>(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<GalileoE1PcpsAmbiguousAcquisitionFpga>(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<GalileoE5aPcpsAcquisitionFpga>(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<GpsL5iPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
args.freq_band = 1;

View File

@@ -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_");

View File

@@ -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<Fpga_Switch> switch_fpga;
switch_fpga = std::make_shared<Fpga_Switch>("/dev/uio1");
switch_fpga = std::make_shared<Fpga_Switch>();
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<unsigned int>(std::round(static_cast<double>(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<unsigned int>(std::round(static_cast<double>(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<unsigned int>(std::round(static_cast<double>(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<unsigned int>(std::round(static_cast<double>(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<AcquisitionInterface> 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<GpsL1CaPcpsAcquisitionFpga>(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<GalileoE1PcpsAmbiguousAcquisitionFpga>(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<GalileoE5aPcpsAcquisitionFpga>(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<GpsL5iPcpsAcquisitionFpga>(config.get(), "Acquisition", 0, 0);
args.freq_band = 1;