mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-07 07:50:32 +00:00
Merge branch 'osnma-cesare' of https://github.com/cesaaargm/osnma into osnma-cesare
This commit is contained in:
commit
34ddbb80f1
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,4 +28,3 @@ HAS_*
|
||||
gnss_sdr_pvt.nmea
|
||||
build-debug/
|
||||
build-release/
|
||||
|
||||
|
1
AUTHORS
1
AUTHORS
@ -64,6 +64,7 @@ Marc Sales marcsales92@gmail.com Contributor
|
||||
Piyush Gupta piyush04111999@gmail.com Contributor
|
||||
Rodrigo Muñoz rodrigo.munoz@proteinlab.cl Contributor
|
||||
Stefan van der Linden spvdlinden@gmail.com Contributor
|
||||
Víctor Castillo-Agüero victorcastilloaguero@gmail.com Contributor
|
||||
Will Silberman wsilberm@google.com Contributor
|
||||
Carlos Paniego carpanie@hotmail.com Artwork
|
||||
|
||||
|
@ -34,6 +34,11 @@ authors:
|
||||
email: mara.branzanti@gmail.com
|
||||
family-names: Branzanti
|
||||
given-names: Mara
|
||||
- alias: castle055
|
||||
affiliation: "Instituto Nacional de Técnica Aeroespacial"
|
||||
email: victorcastilloaguero@gmail.com
|
||||
family-names: "Castillo-Agüero"
|
||||
given-names: Víctor
|
||||
- alias: acebrianjuan
|
||||
email: acebrianjuan@gmail.com
|
||||
family-names: "Cebrián-Juan"
|
||||
|
178
CMakeLists.txt
178
CMakeLists.txt
@ -57,6 +57,8 @@ option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal
|
||||
|
||||
option(ENABLE_ZMQ "Enable GNU Radio ZeroMQ Messaging, requires gr-zeromq" ON)
|
||||
|
||||
option(ENABLE_ION "Enable ION GNSS-SDR Metadata Standard signal source" OFF)
|
||||
|
||||
# Performance analysis tools
|
||||
option(ENABLE_GPERFTOOLS "Enable linking to Gperftools libraries (tcmalloc and profiler)" OFF)
|
||||
|
||||
@ -358,12 +360,12 @@ 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.3")
|
||||
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "28.0")
|
||||
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.14")
|
||||
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")
|
||||
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.9.0")
|
||||
set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7")
|
||||
set(GNSSSDR_ABSL_LOCAL_VERSION "origin/master") # live at head (see https://abseil.io/about/releases)
|
||||
|
||||
@ -3252,7 +3254,7 @@ set_package_properties(LIBIIO PROPERTIES
|
||||
PURPOSE "Used for communication with the AD9361 chipset."
|
||||
TYPE OPTIONAL
|
||||
)
|
||||
if(ENABLE_AD9361 OR ENABLE_FMCOMMS2)
|
||||
if(ENABLE_AD9361 OR ENABLE_FMCOMMS2 OR ENABLE_PLUTOSDR)
|
||||
if(NOT LIBIIO_FOUND)
|
||||
message(STATUS "libiio not found, its installation is required.")
|
||||
message(STATUS "Please build and install the following projects:")
|
||||
@ -3270,6 +3272,161 @@ if(ENABLE_AD9361 OR ENABLE_FMCOMMS2)
|
||||
endif()
|
||||
|
||||
|
||||
################################################################################
|
||||
# ION GNSS-SDR Metadata Standard https://sdr.ion.org/ (OPTIONAL)
|
||||
################################################################################
|
||||
if(CMAKE_VERSION VERSION_LESS 3.14)
|
||||
set(ENABLE_ION OFF) # FetchContent_MakeAvailable is available from CMake 3.14
|
||||
endif()
|
||||
if(ENABLE_ION)
|
||||
include(FetchContent)
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
|
||||
FetchContent_Declare(
|
||||
gnss_metadata_standard
|
||||
GIT_REPOSITORY https://github.com/IonMetadataWorkingGroup/GNSS-Metadata-Standard
|
||||
GIT_TAG 220d116e10db5e403e21b77a1fa25aa35feda198
|
||||
SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/gnss-metadata-standard
|
||||
BINARY_DIR ${GNSSSDR_BINARY_DIR}/gnss-metadata-standard
|
||||
)
|
||||
FetchContent_MakeAvailable(gnss_metadata_standard)
|
||||
|
||||
if(NOT TARGET ION::ion)
|
||||
add_library(ION::ion STATIC IMPORTED)
|
||||
add_dependencies(ION::ion gnss_metadata_standard)
|
||||
if(CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
set_target_properties(ION::ion PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
|
||||
IMPORTED_LOCATION_DEBUG "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
IMPORTED_LOCATION_RELEASE "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Release/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
IMPORTED_LOCATION_RELWITHDEBINFO "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
IMPORTED_LOCATION_MINSIZEREL "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard/source/api/inc"
|
||||
)
|
||||
set_property(TARGET ION::ion APPEND PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES
|
||||
"$<$<CONFIG:Debug>:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>"
|
||||
"$<$<CONFIG:Release>:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Release/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Release/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>"
|
||||
"$<$<CONFIG:RelWithDebInfo>:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>"
|
||||
"$<$<CONFIG:MinSizeRel>:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>"
|
||||
"$<$<CONFIG:NoOptWithASM>:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>"
|
||||
"$<$<CONFIG:Coverage>:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>"
|
||||
"$<$<CONFIG:O2WithASM>:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>"
|
||||
"$<$<CONFIG:O3WithASM>:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>"
|
||||
"$<$<CONFIG:ASAN>:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>"
|
||||
)
|
||||
else()
|
||||
set_target_properties(ION::ion PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
|
||||
IMPORTED_LOCATION "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard/source/api/inc"
|
||||
INTERFACE_LINK_LIBRARIES "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
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()
|
||||
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Check signal sources related to FPGA only.
|
||||
@ -3573,23 +3730,24 @@ add_subdirectory(src)
|
||||
add_feature_info(ENABLE_UHD ENABLE_UHD "Enables UHD_Signal_Source for using RF front-ends from the USRP family. Requires gr-uhd.")
|
||||
add_feature_info(ENABLE_OSMOSDR ENABLE_OSMOSDR "Enables Osmosdr_Signal_Source and RtlTcp_Signal_Source for using RF front-ends compatible with the OsmoSDR driver. Requires gr-osmosdr.")
|
||||
add_feature_info(ENABLE_LIMESDR ENABLE_LIMESDR "Enables Limesdr_Signal_Source. Requires gr-limesdr.")
|
||||
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_FMCOMMS2 ENABLE_FMCOMMS2 "Enables Fmcomms2_Signal_Source for FMCOMMS2/3/4 devices. Requires libiio, libad9361-dev, and gr-iio.")
|
||||
add_feature_info(ENABLE_PLUTOSDR ENABLE_PLUTOSDR "Enables Plutosdr_Signal_Source and Ad936x_Custom_Signal_Source for using ADALM-PLUTO boards. Requires libiio, libad9361-dev, and gr-iio.")
|
||||
add_feature_info(ENABLE_AD936X_SDR ENABLE_AD936X_SDR "Enables Ad936x_Custom_Signal_Source for using ADALM-PLUTO boards with custom firmware. Requires libiio and libad9361-dev.")
|
||||
add_feature_info(ENABLE_FPGA ENABLE_FPGA "Enables building of processing blocks for FPGA offloading.")
|
||||
add_feature_info(ENABLE_AD9361 ENABLE_AD9361 "Enables ADRV9361_Z7035_Signal_Source_FPGA and the FMCOMMS5_Signal_Source_FPGA for FPGA SoC devices with the AD9361 chipset. Requires libiio, libad9361-dev, and -DENABLE_FPGA=ON.")
|
||||
add_feature_info(ENABLE_MAX2771 ENABLE_MAX2771 "Enables FPGA_MAX2771_EVKIT_Signal_Source for FPGA SoC devices with the with the MAX2771 chipset. Requires the spidev driver and -DENABLE_FPGA=ON.")
|
||||
add_feature_info(ENABLE_DMA_PROXY ENABLE_DMA_PROXY "Enables DMA_Signal_Source_FPGA for file post-processing in FPGA SoC devices. Requires the DMA Proxy driver and -DENABLE_FPGA=ON.")
|
||||
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.")
|
||||
add_feature_info(ENABLE_ARRAY ENABLE_ARRAY "Enables Raw_Array_Signal_Source and Array_Signal_Conditioner for using CTTC's antenna array. Requires gr-dbfcttc.")
|
||||
add_feature_info(ENABLE_ZMQ ENABLE_ZMQ "Enables ZMQ_Signal_Source for GNU Radio ZeroMQ messages. Requires gr-zeromq.")
|
||||
add_feature_info(ENABLE_ION ENABLE_ION "Enables ION_GSMS_Signal_Source for the ION Metadata Standard.")
|
||||
add_feature_info(ENABLE_GPERFTOOLS ENABLE_GPERFTOOLS "Enables performance analysis. Requires Gperftools.")
|
||||
add_feature_info(ENABLE_GPROF ENABLE_GPROF "Enables performance analysis with 'gprof'.")
|
||||
add_feature_info(ENABLE_CLANG_TIDY ENABLE_CLANG_TIDY "Runs clang-tidy along with the compiler. Requires Clang.")
|
||||
add_feature_info(ENABLE_PROFILING ENABLE_PROFILING "Runs volk_gnsssdr_profile at the end of the building.")
|
||||
add_feature_info(ENABLE_OPENCL ENABLE_OPENCL "Enables GPS_L1_CA_PCPS_OpenCl_Acquisition (experimental). Requires OpenCL.")
|
||||
add_feature_info(ENABLE_CUDA ENABLE_CUDA "Enables GPS_L1_CA_DLL_PLL_Tracking_GPU (experimental). Requires CUDA.")
|
||||
add_feature_info(ENABLE_FPGA ENABLE_FPGA "Enables building of processing blocks for FPGA offloading.")
|
||||
add_feature_info(ENABLE_ARMA_NO_DEBUG ENABLE_ARMA_NO_DEBUG "Enables passing the ARMA_NO_DEBUG macro to Armadillo, hence disabling bound checking.")
|
||||
add_feature_info(ENABLE_PACKAGING ENABLE_PACKAGING "Enables software packaging.")
|
||||
add_feature_info(ENABLE_OWN_GLOG ENABLE_OWN_GLOG "Forces the downloading and building of Google glog.")
|
||||
|
@ -41,6 +41,11 @@ All notable changes to GNSS-SDR will be documented in this file.
|
||||
- `-DENABLE_DMA_PROXY`: Checks if the DMA proxy driver is installed for
|
||||
controlling the DMA in the FPGA and enables its usage.
|
||||
|
||||
- Add the `ION_GSMS_Signal_Source`, which is able to process raw data files
|
||||
described with the
|
||||
[ION GNSS Software Defined Receiver Metadata Standard](https://sdr.ion.org/).
|
||||
It requires the `-DENABLE_ION=ON` building configuration option.
|
||||
|
||||
### Improvements in Portability:
|
||||
|
||||
- Fix building against google-glog 0.7.x.
|
||||
|
@ -227,11 +227,11 @@
|
||||
#endif // defined(CPU_FEATURES_ARCH_X86)
|
||||
|
||||
#if defined(CPU_FEATURES_ARCH_ANY_ARM)
|
||||
#if defined(__ARM_NEON__)
|
||||
#if defined(__ARM_NEON)
|
||||
#define CPU_FEATURES_COMPILED_ANY_ARM_NEON 1
|
||||
#else
|
||||
#define CPU_FEATURES_COMPILED_ANY_ARM_NEON 0
|
||||
#endif // defined(__ARM_NEON__)
|
||||
#endif // defined(__ARM_NEON)
|
||||
#endif // defined(CPU_FEATURES_ARCH_ANY_ARM)
|
||||
|
||||
#if defined(CPU_FEATURES_ARCH_MIPS)
|
||||
|
@ -182,6 +182,31 @@ typedef struct
|
||||
int smef16f16 : 1; // FP16 to FP16 outer product.
|
||||
int mops : 1; // Standardized memory operations.
|
||||
int hbc : 1; // Hinted conditional branches.
|
||||
int sveb16b16 : 1; // Non-widening BFloat16 to BFloat16 arithmetic for SVE2
|
||||
// and SME2.
|
||||
int lrcpc3 : 1; // Load-Acquire RCpc instructions version 3.
|
||||
int lse128 : 1; // 128-bit Atomics.
|
||||
int fpmr : 1; // Floating-point Mode Register.
|
||||
int lut : 1; // Lookup table instructions with 2-bit and 4-bit indices.
|
||||
int faminmax : 1; // Maximum and minimum absolute value instructions.
|
||||
int f8cvt : 1; // FP scaling instructions and FP8 convert instructions.
|
||||
int f8fma : 1; // FP8 to single-precision and half-precision
|
||||
// multiply-accumulate instructions.
|
||||
int f8dp4 : 1; // FP8 to single-precision 4-way dot product FDOT (4-way)
|
||||
// instructions.
|
||||
int f8dp2 : 1; // FP8 to half-precision 2-way dot product FDOT (2-way)
|
||||
// instructions.
|
||||
int f8e4m3 : 1; // Arm FP8 E4M3 format.
|
||||
int f8e5m2 : 1; // Arm FP8 E5M2 format.
|
||||
int smelutv2 : 1; // SME2 lookup table LUTI4 and MOVT instructions.
|
||||
int smef8f16 : 1; // SME2 F8F16 instructions.
|
||||
int smef8f32 : 1; // SME2 F8F32 instructions.
|
||||
int smesf8fma : 1; // SVE2 FP8 to single-precision and half-precision
|
||||
// multiply-accumulate instructions.
|
||||
int smesf8dp4 : 1; // SVE2 FP8 to single-precision 4-way dot product FDOT
|
||||
// (4-way) instructions.
|
||||
int smesf8dp2 : 1; // SVE2 FP8 to half-precision 2-way dot product FDOT
|
||||
// (2-way) instructions.
|
||||
|
||||
// Make sure to update Aarch64FeaturesEnum below if you add a field here.
|
||||
} Aarch64Features;
|
||||
@ -280,6 +305,24 @@ typedef enum
|
||||
AARCH64_SME_F16F16,
|
||||
AARCH64_MOPS,
|
||||
AARCH64_HBC,
|
||||
AARCH64_SVE_B16B16,
|
||||
AARCH64_LRCPC3,
|
||||
AARCH64_LSE128,
|
||||
AARCH64_FPMR,
|
||||
AARCH64_LUT,
|
||||
AARCH64_FAMINMAX,
|
||||
AARCH64_F8CVT,
|
||||
AARCH64_F8FMA,
|
||||
AARCH64_F8DP4,
|
||||
AARCH64_F8DP2,
|
||||
AARCH64_F8E4M3,
|
||||
AARCH64_F8E5M2,
|
||||
AARCH64_SME_LUTV2,
|
||||
AARCH64_SME_F8F16,
|
||||
AARCH64_SME_F8F32,
|
||||
AARCH64_SME_SF8FMA,
|
||||
AARCH64_SME_SF8DP4,
|
||||
AARCH64_SME_SF8DP2,
|
||||
AARCH64_LAST_,
|
||||
} Aarch64FeaturesEnum;
|
||||
|
||||
|
@ -94,6 +94,24 @@ CPU_FEATURES_START_CPP_NAMESPACE
|
||||
#define AARCH64_HWCAP2_SME_F16F16 (1UL << 42)
|
||||
#define AARCH64_HWCAP2_MOPS (1UL << 43)
|
||||
#define AARCH64_HWCAP2_HBC (1UL << 44)
|
||||
#define AARCH64_HWCAP2_SVE_B16B16 (1UL << 45)
|
||||
#define AARCH64_HWCAP2_LRCPC3 (1UL << 46)
|
||||
#define AARCH64_HWCAP2_LSE128 (1UL << 47)
|
||||
#define AARCH64_HWCAP2_FPMR (1UL << 48)
|
||||
#define AARCH64_HWCAP2_LUT (1UL << 49)
|
||||
#define AARCH64_HWCAP2_FAMINMAX (1UL << 50)
|
||||
#define AARCH64_HWCAP2_F8CVT (1UL << 51)
|
||||
#define AARCH64_HWCAP2_F8FMA (1UL << 52)
|
||||
#define AARCH64_HWCAP2_F8DP4 (1UL << 53)
|
||||
#define AARCH64_HWCAP2_F8DP2 (1UL << 54)
|
||||
#define AARCH64_HWCAP2_F8E4M3 (1UL << 55)
|
||||
#define AARCH64_HWCAP2_F8E5M2 (1UL << 56)
|
||||
#define AARCH64_HWCAP2_SME_LUTV2 (1UL << 57)
|
||||
#define AARCH64_HWCAP2_SME_F8F16 (1UL << 58)
|
||||
#define AARCH64_HWCAP2_SME_F8F32 (1UL << 59)
|
||||
#define AARCH64_HWCAP2_SME_SF8FMA (1UL << 60)
|
||||
#define AARCH64_HWCAP2_SME_SF8DP4 (1UL << 61)
|
||||
#define AARCH64_HWCAP2_SME_SF8DP2 (1UL << 62)
|
||||
|
||||
// http://elixir.free-electrons.com/linux/latest/source/arch/arm/include/uapi/asm/hwcap.h
|
||||
#define ARM_HWCAP_SWP (1UL << 0)
|
||||
|
@ -103,7 +103,28 @@
|
||||
LINE(AARCH64_SME_F16F16, smef16f16, "smef16f16", 0, \
|
||||
AARCH64_HWCAP2_SME_F16F16) \
|
||||
LINE(AARCH64_MOPS, mops, "mops", 0, AARCH64_HWCAP2_MOPS) \
|
||||
LINE(AARCH64_HBC, hbc, "hbc", 0, AARCH64_HWCAP2_HBC)
|
||||
LINE(AARCH64_HBC, hbc, "hbc", 0, AARCH64_HWCAP2_HBC) \
|
||||
LINE(AARCH64_SVE_B16B16, sveb16b16, "sveb16b16", 0, \
|
||||
AARCH64_HWCAP2_SVE_B16B16) \
|
||||
LINE(AARCH64_LRCPC3, lrcpc3, "lrcpc3", 0, AARCH64_HWCAP2_LRCPC3) \
|
||||
LINE(AARCH64_LSE128, lse128, "lse128", 0, AARCH64_HWCAP2_LSE128) \
|
||||
LINE(AARCH64_FPMR, fpmr, "fpmr", 0, AARCH64_HWCAP2_FPMR) \
|
||||
LINE(AARCH64_LUT, lut, "lut", 0, AARCH64_HWCAP2_LUT) \
|
||||
LINE(AARCH64_FAMINMAX, faminmax, "faminmax", 0, AARCH64_HWCAP2_FAMINMAX) \
|
||||
LINE(AARCH64_F8CVT, f8cvt, "f8cvt", 0, AARCH64_HWCAP2_F8CVT) \
|
||||
LINE(AARCH64_F8FMA, f8fma, "f8fma", 0, AARCH64_HWCAP2_F8FMA) \
|
||||
LINE(AARCH64_F8DP4, f8dp4, "f8dp4", 0, AARCH64_HWCAP2_F8DP4) \
|
||||
LINE(AARCH64_F8DP2, f8dp2, "f8dp2", 0, AARCH64_HWCAP2_F8DP2) \
|
||||
LINE(AARCH64_F8E4M3, f8e4m3, "f8e4m3", 0, AARCH64_HWCAP2_F8E4M3) \
|
||||
LINE(AARCH64_F8E5M2, f8e5m2, "f8e5m2", 0, AARCH64_HWCAP2_F8E5M2) \
|
||||
LINE(AARCH64_SME_LUTV2, smelutv2, "smelutv1", 0, AARCH64_HWCAP2_SME_LUTV2) \
|
||||
LINE(AARCH64_SME_F8F16, smef8f16, "smef8f16", 0, AARCH64_HWCAP2_SME_F8F16) \
|
||||
LINE(AARCH64_SME_F8F32, smef8f32, "smef8f32", 0, AARCH64_HWCAP2_SME_F8F32) \
|
||||
LINE(AARCH64_SME_SF8FMA, smesf8fma, "smesf8fma", 0, \
|
||||
AARCH64_HWCAP2_SME_SF8FMA) \
|
||||
LINE(AARCH64_SME_SF8DP4, smesf8dp4, "smesf8dp4", 0, \
|
||||
AARCH64_HWCAP2_SME_SF8DP4) \
|
||||
LINE(AARCH64_SME_SF8DP2, smesf8dp2, "smesf8dp2", 0, AARCH64_HWCAP2_SME_SF8DP2)
|
||||
#define INTROSPECTION_PREFIX Aarch64
|
||||
#define INTROSPECTION_ENUM_PREFIX AARCH64
|
||||
#include "define_introspection_and_hwcaps.inl"
|
@ -326,6 +326,24 @@ CPU revision : 3)");
|
||||
EXPECT_FALSE(info.features.smef16f16);
|
||||
EXPECT_FALSE(info.features.mops);
|
||||
EXPECT_FALSE(info.features.hbc);
|
||||
EXPECT_FALSE(info.features.sveb16b16);
|
||||
EXPECT_FALSE(info.features.lrcpc3);
|
||||
EXPECT_FALSE(info.features.lse128);
|
||||
EXPECT_FALSE(info.features.fpmr);
|
||||
EXPECT_FALSE(info.features.lut);
|
||||
EXPECT_FALSE(info.features.faminmax);
|
||||
EXPECT_FALSE(info.features.f8cvt);
|
||||
EXPECT_FALSE(info.features.f8fma);
|
||||
EXPECT_FALSE(info.features.f8dp4);
|
||||
EXPECT_FALSE(info.features.f8dp2);
|
||||
EXPECT_FALSE(info.features.f8e4m3);
|
||||
EXPECT_FALSE(info.features.f8e5m2);
|
||||
EXPECT_FALSE(info.features.smelutv2);
|
||||
EXPECT_FALSE(info.features.smef8f16);
|
||||
EXPECT_FALSE(info.features.smef8f32);
|
||||
EXPECT_FALSE(info.features.smesf8fma);
|
||||
EXPECT_FALSE(info.features.smesf8dp4);
|
||||
EXPECT_FALSE(info.features.smesf8dp2);
|
||||
}
|
||||
#elif defined(CPU_FEATURES_OS_MACOS)
|
||||
TEST_F(CpuidAarch64Test, FromDarwinSysctlFromName)
|
||||
|
@ -25,6 +25,14 @@ if(ENABLE_PLUTOSDR)
|
||||
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ad936x_custom_signal_source.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_AD936X_SDR AND NOT ENABLE_PLUTOSDR)
|
||||
##############################################
|
||||
# CUSTOM AD936X IIO SOURCE
|
||||
##############################################
|
||||
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} ad936x_custom_signal_source.cc)
|
||||
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ad936x_custom_signal_source.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FMCOMMS2)
|
||||
###############################################
|
||||
# FMCOMMS2 based SDR Hardware
|
||||
@ -103,6 +111,11 @@ if(ENABLE_ZMQ)
|
||||
list(APPEND OPT_DRIVER_HEADERS zmq_signal_source.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ION)
|
||||
list(APPEND OPT_DRIVER_SOURCES ion_gsms_signal_source.cc)
|
||||
list(APPEND OPT_DRIVER_HEADERS ion_gsms_signal_source.h)
|
||||
endif()
|
||||
|
||||
set(SIGNAL_SOURCE_ADAPTER_SOURCES
|
||||
signal_source_base.cc
|
||||
file_source_base.cc
|
||||
@ -169,7 +182,7 @@ target_include_directories(signal_source_adapters
|
||||
${GNSSSDR_SOURCE_DIR}/src/core/interfaces
|
||||
)
|
||||
|
||||
if(ENABLE_FPGA OR ENABLE_AD9361)
|
||||
if(ENABLE_FPGA OR ENABLE_AD9361 OR ENABLE_ION)
|
||||
target_link_libraries(signal_source_adapters
|
||||
PUBLIC
|
||||
signal_source_libs
|
||||
@ -239,14 +252,14 @@ if(ENABLE_LIMESDR AND GRLIMESDR_FOUND)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_AD9361 AND LIBIIO_FOUND)
|
||||
if(LIBIIO_FOUND)
|
||||
target_link_libraries(signal_source_adapters
|
||||
PRIVATE
|
||||
Iio::iio
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_AD9361 OR ENABLE_FMCOMMS2 OR ENABLE_PLUTOSDR)
|
||||
if(ENABLE_AD9361 OR ENABLE_FMCOMMS2 OR ENABLE_PLUTOSDR OR ENABLE_AD936X_SDR)
|
||||
if(LIBAD9361_VERSION)
|
||||
if(LIBAD9361_VERSION VERSION_GREATER 0.1)
|
||||
target_compile_definitions(signal_source_adapters
|
||||
|
@ -76,8 +76,11 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface*
|
||||
item_size_ = sizeof(gr_complex);
|
||||
// 1. Make the driver instance
|
||||
bool customsamplesize = false;
|
||||
if (ssize_ != 12 or spattern_ == true) customsamplesize = true; // custom FPGA DMA firmware
|
||||
if (ssize_ == 12) // default original FPGA DMA firmware
|
||||
if (ssize_ != 12 || spattern_ == true)
|
||||
{
|
||||
customsamplesize = true; // custom FPGA DMA firmware
|
||||
}
|
||||
if (ssize_ == 12) // default original FPGA DMA firmware
|
||||
{
|
||||
ssize_ = 16; // set to 16 bits and do not try to change sample size
|
||||
}
|
||||
@ -153,8 +156,14 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface*
|
||||
|
||||
for (int n = 0; n < n_channels; n++)
|
||||
{
|
||||
if (n == 0) inverted_spectrum_vec.push_back(inverted_spectrum_ch0_);
|
||||
if (n == 1) inverted_spectrum_vec.push_back(inverted_spectrum_ch1_);
|
||||
if (n == 0)
|
||||
{
|
||||
inverted_spectrum_vec.push_back(inverted_spectrum_ch0_);
|
||||
}
|
||||
if (n == 1)
|
||||
{
|
||||
inverted_spectrum_vec.push_back(inverted_spectrum_ch1_);
|
||||
}
|
||||
}
|
||||
|
||||
for (int n = 0; n < n_channels; n++)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* \file adrv9361_z7035_signal_source_fpga.cc
|
||||
* \brief signal source for the Analog Devices ADRV9361-Z7035 evaluation board
|
||||
* \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.
|
||||
@ -51,14 +51,14 @@ Adrv9361z7035SignalSourceFPGA::Adrv9361z7035SignalSourceFPGA(const Configuration
|
||||
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_source_(configuration->property(role + ".filter_source", std::string("Off"))),
|
||||
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))),
|
||||
freq0_(configuration->property(role + ".freq", 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))),
|
||||
@ -70,7 +70,6 @@ Adrv9361z7035SignalSourceFPGA::Adrv9361z7035SignalSourceFPGA(const Configuration
|
||||
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)),
|
||||
@ -98,15 +97,6 @@ Adrv9361z7035SignalSourceFPGA::Adrv9361z7035SignalSourceFPGA(const Configuration
|
||||
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);
|
||||
|
||||
@ -190,12 +180,15 @@ Adrv9361z7035SignalSourceFPGA::Adrv9361z7035SignalSourceFPGA(const Configuration
|
||||
}
|
||||
|
||||
std::cout << "LO frequency : " << freq0_ << " Hz\n";
|
||||
|
||||
uint64_t freq1 = 0; // The local oscillator frequency of the ADRV9361-B is not used when using the ADRV9361-Z7035 board.
|
||||
|
||||
try
|
||||
{
|
||||
config_ad9361_rx_local(bandwidth_,
|
||||
sample_rate_,
|
||||
freq0_,
|
||||
freq1_,
|
||||
freq1,
|
||||
rf_port_select_,
|
||||
rx1_enable_,
|
||||
rx2_enable_,
|
||||
@ -257,7 +250,6 @@ Adrv9361z7035SignalSourceFPGA::Adrv9361z7035SignalSourceFPGA(const Configuration
|
||||
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_)
|
||||
{
|
||||
@ -278,15 +270,23 @@ Adrv9361z7035SignalSourceFPGA::Adrv9361z7035SignalSourceFPGA(const Configuration
|
||||
|
||||
Adrv9361z7035SignalSourceFPGA::~Adrv9361z7035SignalSourceFPGA()
|
||||
{
|
||||
/* cleanup and exit */
|
||||
|
||||
// cleanup and exit
|
||||
if (rf_shutdown_)
|
||||
{
|
||||
std::cout << "* AD9361 Disabling RX streaming channels\n";
|
||||
if (!disable_ad9361_rx_local())
|
||||
try
|
||||
{
|
||||
LOG(WARNING) << "Problem shutting down the AD9361 RX channels";
|
||||
if (!disable_ad9361_rx_local())
|
||||
{
|
||||
LOG(WARNING) << "Problem shutting down the AD9361 RX channels";
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LOG(WARNING) << "Problem shutting down the AD9361 RX channels: " << e.what();
|
||||
std::cerr << "Problem shutting down the AD9361 RX channels: " << e.what() << '\n';
|
||||
}
|
||||
|
||||
if (enable_dds_lo_)
|
||||
{
|
||||
try
|
||||
@ -301,24 +301,27 @@ Adrv9361z7035SignalSourceFPGA::~Adrv9361z7035SignalSourceFPGA()
|
||||
}
|
||||
|
||||
// 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();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock_buffer_monitor(buffer_monitor_mutex);
|
||||
enable_ovf_check_buffer_monitor_active_ = false;
|
||||
}
|
||||
|
||||
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();
|
||||
bool bit_selection_enabled = false;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock_dyn_bit_sel(dynamic_bit_selection_mutex);
|
||||
bit_selection_enabled = enable_dynamic_bit_selection_;
|
||||
}
|
||||
|
||||
if (bit_selection_enabled == true)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(dynamic_bit_selection_mutex);
|
||||
enable_dynamic_bit_selection_ = false;
|
||||
lock.unlock();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(dynamic_bit_selection_mutex);
|
||||
enable_dynamic_bit_selection_ = false;
|
||||
}
|
||||
|
||||
if (thread_dynamic_bit_selection.joinable())
|
||||
{
|
||||
@ -337,12 +340,11 @@ void Adrv9361z7035SignalSourceFPGA::run_dynamic_bit_selection_process()
|
||||
// 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);
|
||||
std::lock_guard<std::mutex> lock(dynamic_bit_selection_mutex);
|
||||
if (enable_dynamic_bit_selection_ == false)
|
||||
{
|
||||
dynamic_bit_selection_active = false;
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -357,12 +359,11 @@ void Adrv9361z7035SignalSourceFPGA::run_buffer_monitor_process()
|
||||
{
|
||||
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);
|
||||
std::lock_guard<std::mutex> lock(buffer_monitor_mutex);
|
||||
if (enable_ovf_check_buffer_monitor_active_ == false)
|
||||
{
|
||||
enable_ovf_check_buffer_monitor_active = false;
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* \file adrv9361_z7035_signal_source_fpga.h
|
||||
* \brief signal source for the Analog Devices ADRV9361-Z7035 evaluation board
|
||||
* \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.
|
||||
@ -23,7 +23,6 @@
|
||||
|
||||
#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"
|
||||
@ -78,13 +77,14 @@ private:
|
||||
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();
|
||||
|
||||
mutable std::mutex dynamic_bit_selection_mutex;
|
||||
mutable std::mutex buffer_monitor_mutex;
|
||||
|
||||
std::thread thread_dynamic_bit_selection;
|
||||
std::thread thread_buffer_monitor;
|
||||
|
||||
@ -92,9 +92,6 @@ private:
|
||||
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_;
|
||||
@ -109,7 +106,6 @@ private:
|
||||
double tx_attenuation_db_;
|
||||
|
||||
uint64_t freq0_; // frequency of local oscillator for ADRV9361-A 0
|
||||
uint64_t freq1_; // frequency of local oscillator for ADRV9361-B (if present)
|
||||
uint64_t sample_rate_;
|
||||
uint64_t bandwidth_;
|
||||
uint64_t freq_dds_tx_hz_;
|
||||
@ -124,7 +120,6 @@ private:
|
||||
size_t item_size_;
|
||||
|
||||
bool enable_dds_lo_;
|
||||
bool filter_auto_;
|
||||
bool quadrature_;
|
||||
bool rf_dc_;
|
||||
bool bb_dc_;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* \file fmcomms5_signal_source_fpga.cc
|
||||
* \brief signal source for the Analog Devices FMCOMMS5 directly connected
|
||||
* \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.
|
||||
@ -51,6 +51,7 @@ Fmcomms5SignalSourceFPGA::Fmcomms5SignalSourceFPGA(const ConfigurationInterface
|
||||
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_source_(configuration->property(role + ".filter_source", std::string("Off"))),
|
||||
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)),
|
||||
@ -63,7 +64,6 @@ Fmcomms5SignalSourceFPGA::Fmcomms5SignalSourceFPGA(const ConfigurationInterface
|
||||
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)),
|
||||
@ -86,15 +86,6 @@ Fmcomms5SignalSourceFPGA::Fmcomms5SignalSourceFPGA(const ConfigurationInterface
|
||||
|
||||
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);
|
||||
|
||||
@ -217,7 +208,6 @@ Fmcomms5SignalSourceFPGA::Fmcomms5SignalSourceFPGA(const ConfigurationInterface
|
||||
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_)
|
||||
{
|
||||
@ -238,36 +228,45 @@ Fmcomms5SignalSourceFPGA::Fmcomms5SignalSourceFPGA(const ConfigurationInterface
|
||||
|
||||
Fmcomms5SignalSourceFPGA::~Fmcomms5SignalSourceFPGA()
|
||||
{
|
||||
/* cleanup and exit */
|
||||
|
||||
// cleanup and exit
|
||||
if (rf_shutdown_)
|
||||
{
|
||||
std::cout << "* Disabling RX streaming channels\n";
|
||||
if (!disable_ad9361_rx_local())
|
||||
try
|
||||
{
|
||||
LOG(WARNING) << "Problem shutting down the AD9361 RX channels";
|
||||
if (!disable_ad9361_rx_local())
|
||||
{
|
||||
LOG(WARNING) << "Problem shutting down the AD9361 RX channels";
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
std::cerr << "Problem shutting down the AD9361 RX channels: " << e.what() << '\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();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock_buffer_monitor(buffer_monitor_mutex);
|
||||
enable_ovf_check_buffer_monitor_active_ = false;
|
||||
}
|
||||
|
||||
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();
|
||||
bool bit_selection_enabled = false;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock_dyn_bit_sel(dynamic_bit_selection_mutex);
|
||||
bit_selection_enabled = enable_dynamic_bit_selection_;
|
||||
}
|
||||
|
||||
if (bit_selection_enabled == true)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(dynamic_bit_selection_mutex);
|
||||
enable_dynamic_bit_selection_ = false;
|
||||
lock.unlock();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(dynamic_bit_selection_mutex);
|
||||
enable_dynamic_bit_selection_ = false;
|
||||
}
|
||||
|
||||
if (thread_dynamic_bit_selection.joinable())
|
||||
{
|
||||
@ -286,12 +285,11 @@ void Fmcomms5SignalSourceFPGA::run_dynamic_bit_selection_process()
|
||||
// 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);
|
||||
std::lock_guard<std::mutex> lock(dynamic_bit_selection_mutex);
|
||||
if (enable_dynamic_bit_selection_ == false)
|
||||
{
|
||||
dynamic_bit_selection_active = false;
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,12 +304,11 @@ void Fmcomms5SignalSourceFPGA::run_buffer_monitor_process()
|
||||
{
|
||||
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);
|
||||
std::lock_guard<std::mutex> lock(buffer_monitor_mutex);
|
||||
if (enable_ovf_check_buffer_monitor_active_ == false)
|
||||
{
|
||||
enable_ovf_check_buffer_monitor_active = false;
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* \file fmcomms5_signal_source_fpga.h
|
||||
* \brief signal source for the Analog Devices FMCOMMS5 directly connected
|
||||
* \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.
|
||||
@ -23,7 +23,6 @@
|
||||
|
||||
#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"
|
||||
@ -67,7 +66,6 @@ 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;
|
||||
@ -78,13 +76,14 @@ private:
|
||||
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();
|
||||
|
||||
mutable std::mutex dynamic_bit_selection_mutex;
|
||||
mutable std::mutex buffer_monitor_mutex;
|
||||
|
||||
std::thread thread_dynamic_bit_selection;
|
||||
std::thread thread_buffer_monitor;
|
||||
|
||||
@ -92,9 +91,6 @@ private:
|
||||
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_;
|
||||
@ -117,7 +113,6 @@ private:
|
||||
|
||||
size_t item_size_;
|
||||
|
||||
bool filter_auto_;
|
||||
bool quadrature_;
|
||||
bool rf_dc_;
|
||||
bool bb_dc_;
|
||||
|
239
src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc
Normal file
239
src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc
Normal file
@ -0,0 +1,239 @@
|
||||
/*!
|
||||
* \file ion_gsms_signal_source.h
|
||||
* \brief GNSS-SDR Signal Source that reads sample streams following ION's GNSS-SDR metadata standard
|
||||
* \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* 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 "ion_gsms_signal_source.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_string_literals.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include <gnuradio/blocks/copy.h>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <unordered_set>
|
||||
|
||||
#if USE_GLOG_AND_GFLAGS
|
||||
#include <glog/logging.h>
|
||||
#else
|
||||
#include <absl/log/log.h>
|
||||
#endif
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<std::string> parse_comma_list(const std::string& str)
|
||||
{
|
||||
std::vector<std::string> list{};
|
||||
std::size_t prev_comma_at{0};
|
||||
|
||||
while (prev_comma_at < str.size())
|
||||
{
|
||||
std::size_t comma_at = str.find_first_of(',', prev_comma_at);
|
||||
if (comma_at == std::string::npos)
|
||||
{
|
||||
comma_at = str.size();
|
||||
}
|
||||
list.emplace_back(str.substr(prev_comma_at, (comma_at - prev_comma_at)));
|
||||
prev_comma_at = comma_at + 1;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configuration,
|
||||
const std::string& role,
|
||||
unsigned int in_streams,
|
||||
unsigned int out_streams,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||
: SignalSourceBase(configuration, role, "ION_GSMS_Signal_Source"s),
|
||||
stream_ids_(parse_comma_list(configuration->property(role + ".streams"s, ""s))),
|
||||
metadata_filepath_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)),
|
||||
in_streams_(in_streams),
|
||||
out_streams_(out_streams)
|
||||
{
|
||||
if (in_streams_ > 0)
|
||||
{
|
||||
LOG(ERROR) << "A signal source does not have an input stream";
|
||||
}
|
||||
if (out_streams_ <= 0)
|
||||
{
|
||||
LOG(ERROR) << "A signal source does not have an output stream";
|
||||
}
|
||||
|
||||
// Parse XML metadata file
|
||||
load_metadata();
|
||||
|
||||
// Make source vector
|
||||
sources_ = make_stream_sources(stream_ids_);
|
||||
|
||||
for (const auto& source : sources_)
|
||||
{
|
||||
for (std::size_t i = 0; i < source->output_stream_count(); ++i)
|
||||
{
|
||||
copy_blocks_.emplace_back(gr::blocks::copy::make(source->output_stream_item_size(i)));
|
||||
valves_.emplace_back(gnss_sdr_make_valve(source->output_stream_item_size(i), source->output_stream_total_sample_count(i), queue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IONGSMSSignalSource::load_metadata()
|
||||
{
|
||||
metadata_ = std::make_shared<GnssMetadata::Metadata>();
|
||||
try
|
||||
{
|
||||
GnssMetadata::XmlProcessor xml_proc;
|
||||
if (!xml_proc.Load(metadata_filepath_.c_str(), false, *metadata_))
|
||||
{
|
||||
LOG(WARNING) << "Could not load XML metadata file " << metadata_filepath_;
|
||||
std::cerr << "Could not load XML metadata file " << metadata_filepath_ << std::endl;
|
||||
std::cout << "GNSS-SDR program ended.\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
catch (GnssMetadata::ApiException& e)
|
||||
{
|
||||
LOG(WARNING) << "API Exception while loading XML metadata file: " << std::to_string(e.Error());
|
||||
std::cerr << "Could not load XML metadata file " << metadata_filepath_ << " : " << std::to_string(e.Error()) << std::endl;
|
||||
std::cout << "GNSS-SDR program ended.\n";
|
||||
exit(1);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG(WARNING) << "Exception while loading XML metadata file: " << e.what();
|
||||
std::cerr << "Could not load XML metadata file " << metadata_filepath_ << " : " << e.what() << std::endl;
|
||||
std::cout << "GNSS-SDR program ended.\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<IONGSMSFileSource::sptr> IONGSMSSignalSource::make_stream_sources(const std::vector<std::string>& stream_ids) const
|
||||
{
|
||||
std::vector<IONGSMSFileSource::sptr> sources{};
|
||||
for (const auto& file : metadata_->Files())
|
||||
{
|
||||
for (const auto& lane : metadata_->Lanes())
|
||||
{
|
||||
if (lane.Id() == file.Lane().Id())
|
||||
{
|
||||
for (const auto& block : lane.Blocks())
|
||||
{
|
||||
bool block_done = false;
|
||||
for (const auto& chunk : block.Chunks())
|
||||
{
|
||||
for (const auto& lump : chunk.Lumps())
|
||||
{
|
||||
for (const auto& stream : lump.Streams())
|
||||
{
|
||||
bool found = false;
|
||||
for (const auto& stream_id : stream_ids)
|
||||
{
|
||||
if (stream_id == stream.Id())
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
auto source = gnss_make_shared<IONGSMSFileSource>(
|
||||
metadata_filepath_,
|
||||
file,
|
||||
block,
|
||||
stream_ids);
|
||||
|
||||
sources.push_back(source);
|
||||
|
||||
// This file source will take care of any other matching streams in this block
|
||||
// We can skip the rest of this block
|
||||
block_done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (block_done)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (block_done)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sources;
|
||||
}
|
||||
|
||||
|
||||
void IONGSMSSignalSource::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
std::size_t cumulative_index = 0;
|
||||
for (const auto& source : sources_)
|
||||
{
|
||||
for (std::size_t i = 0; i < source->output_stream_count(); ++i, ++cumulative_index)
|
||||
{
|
||||
top_block->connect(source, i, copy_blocks_[cumulative_index], 0);
|
||||
top_block->connect(copy_blocks_[cumulative_index], 0, valves_[cumulative_index], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IONGSMSSignalSource::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
std::size_t cumulative_index = 0;
|
||||
for (const auto& source : sources_)
|
||||
{
|
||||
for (std::size_t i = 0; i < source->output_stream_count(); ++i, ++cumulative_index)
|
||||
{
|
||||
top_block->disconnect(source, i, copy_blocks_[cumulative_index], 0);
|
||||
top_block->disconnect(copy_blocks_[cumulative_index], 0, valves_[cumulative_index], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr IONGSMSSignalSource::get_left_block()
|
||||
{
|
||||
LOG(WARNING) << "Trying to get signal source left block.";
|
||||
// return gr_basic_block_sptr();
|
||||
return IONGSMSFileSource::sptr();
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr IONGSMSSignalSource::get_right_block()
|
||||
{
|
||||
return get_right_block(0);
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr IONGSMSSignalSource::get_right_block(int RF_channel)
|
||||
{
|
||||
if (RF_channel < 0 || RF_channel >= static_cast<int>(copy_blocks_.size()))
|
||||
{
|
||||
LOG(WARNING) << "'RF_channel' out of bounds while trying to get signal source right block.";
|
||||
return valves_[0];
|
||||
}
|
||||
return valves_[RF_channel];
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*!
|
||||
* \file ion_gsms_signal_source.h
|
||||
* \brief GNSS-SDR Signal Source that reads sample streams following ION's GNSS-SDR metadata standard
|
||||
* \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* 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_ION_GSMS_SIGNAL_SOURCE_H
|
||||
#define GNSS_SDR_ION_GSMS_SIGNAL_SOURCE_H
|
||||
|
||||
#include "configuration_interface.h"
|
||||
#include "file_source_base.h"
|
||||
#include "gnss_sdr_timestamp.h"
|
||||
#include "ion_gsms.h"
|
||||
#include <GnssMetadata.h>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
* \{ */
|
||||
/** \addtogroup Signal_Source_adapters
|
||||
* \{ */
|
||||
|
||||
/*!
|
||||
* \brief Class that reads signals samples from a file
|
||||
* and adapts it to a SignalSourceInterface
|
||||
*/
|
||||
class IONGSMSSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
IONGSMSSignalSource(const ConfigurationInterface* configuration, const std::string& role,
|
||||
unsigned int in_streams, unsigned int out_streams,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue);
|
||||
|
||||
~IONGSMSSignalSource() override = default;
|
||||
|
||||
protected:
|
||||
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;
|
||||
gr::basic_block_sptr get_right_block(int RF_channel) override;
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return (*sources_.begin())->output_stream_item_size(0);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<IONGSMSFileSource::sptr> make_stream_sources(const std::vector<std::string>& stream_ids) const;
|
||||
|
||||
void load_metadata();
|
||||
|
||||
std::vector<std::string> stream_ids_;
|
||||
std::vector<IONGSMSFileSource::sptr> sources_;
|
||||
std::vector<gnss_shared_ptr<gr::block>> copy_blocks_;
|
||||
std::vector<gnss_shared_ptr<gr::block>> valves_;
|
||||
|
||||
std::string metadata_filepath_;
|
||||
std::shared_ptr<GnssMetadata::Metadata> metadata_;
|
||||
|
||||
gnss_shared_ptr<Gnss_Sdr_Timestamp> timestamp_block_;
|
||||
std::string timestamp_file_;
|
||||
|
||||
uint32_t in_streams_;
|
||||
uint32_t out_streams_;
|
||||
};
|
||||
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_ION_GSMS_SIGNAL_SOURCE_H
|
@ -140,13 +140,11 @@ MAX2771EVKITSignalSourceFPGA::MAX2771EVKITSignalSourceFPGA(const ConfigurationIn
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<uint32_t> MAX2771EVKITSignalSourceFPGA::setup_regs(void)
|
||||
{
|
||||
std::vector<uint32_t> register_values = std::vector<uint32_t>(MAX2771_NUM_REGS);
|
||||
|
||||
|
||||
auto register_values = std::vector<uint32_t>(MAX2771_NUM_REGS);
|
||||
uint32_t LNA_mode = (LNA_active_) ? 0x0 : 0x2;
|
||||
|
||||
uint32_t Filter_Bandwidth;
|
||||
|
||||
switch (bandwidth_)
|
||||
@ -376,10 +374,10 @@ bool MAX2771EVKITSignalSourceFPGA::configure(std::vector<uint32_t> register_valu
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
MAX2771EVKITSignalSourceFPGA::~MAX2771EVKITSignalSourceFPGA()
|
||||
{
|
||||
/* cleanup and exit */
|
||||
|
||||
// cleanup and exit
|
||||
if (rf_shutdown_)
|
||||
{
|
||||
chipen_ = false;
|
||||
@ -392,7 +390,6 @@ MAX2771EVKITSignalSourceFPGA::~MAX2771EVKITSignalSourceFPGA()
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (configure(register_values))
|
||||
{
|
||||
std::cerr << "Error disabling the MAX2771 device " << '\n';
|
||||
@ -405,9 +402,10 @@ MAX2771EVKITSignalSourceFPGA::~MAX2771EVKITSignalSourceFPGA()
|
||||
}
|
||||
|
||||
// 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();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock_buffer_monitor(buffer_monitor_mutex);
|
||||
enable_ovf_check_buffer_monitor_active_ = false;
|
||||
}
|
||||
|
||||
if (thread_buffer_monitor.joinable())
|
||||
{
|
||||
@ -426,12 +424,11 @@ void MAX2771EVKITSignalSourceFPGA::run_buffer_monitor_process()
|
||||
{
|
||||
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);
|
||||
std::lock_guard<std::mutex> lock(buffer_monitor_mutex);
|
||||
if (enable_ovf_check_buffer_monitor_active_ == false)
|
||||
{
|
||||
enable_ovf_check_buffer_monitor_active = false;
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,6 @@ public:
|
||||
|
||||
std::vector<uint32_t> setup_regs(void);
|
||||
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
@ -130,14 +129,13 @@ private:
|
||||
bool configure(std::vector<uint32_t> register_values);
|
||||
void run_buffer_monitor_process();
|
||||
|
||||
mutable std::mutex buffer_monitor_mutex;
|
||||
|
||||
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_;
|
||||
|
||||
|
@ -10,17 +10,16 @@ if(ENABLE_RAW_UDP AND PCAP_FOUND)
|
||||
list(APPEND OPT_DRIVER_HEADERS gr_complex_ip_packet_source.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_AD936X_SDR)
|
||||
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} gr_complex_ip_packet_source.cc)
|
||||
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} gr_complex_ip_packet_source.h)
|
||||
endif()
|
||||
|
||||
|
||||
if(ENABLE_PLUTOSDR)
|
||||
if(ENABLE_PLUTOSDR OR ENABLE_AD936X_SDR)
|
||||
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} ad936x_iio_source.cc)
|
||||
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ad936x_iio_source.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ION)
|
||||
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} ion_gsms.cc)
|
||||
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ion_gsms.h)
|
||||
endif()
|
||||
|
||||
set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES
|
||||
fifo_reader.cc
|
||||
unpack_byte_2bit_samples.cc
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*!
|
||||
* \file ad936x_iio_source.cc
|
||||
* \brief A direct IIO custom front-end gnss-sdr signal gnuradio block for the AD936x AD front-end family with special FPGA custom functionalities.
|
||||
* \brief A direct IIO custom front-end gnss-sdr signal gnuradio block for the
|
||||
* AD936x AD front-end family with special FPGA custom functionalities.
|
||||
* \author Javier Arribas, jarribas(at)cttc.es
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
@ -33,23 +34,23 @@
|
||||
|
||||
|
||||
ad936x_iio_source_sptr ad936x_iio_make_source_sptr(
|
||||
std::string pluto_uri_,
|
||||
std::string board_type_,
|
||||
long long bandwidth_,
|
||||
long long sample_rate_,
|
||||
long long freq_,
|
||||
std::string rf_port_select_,
|
||||
std::string rf_filter,
|
||||
std::string gain_mode_rx0_,
|
||||
std::string gain_mode_rx1_,
|
||||
const std::string& pluto_uri_,
|
||||
const std::string& board_type_,
|
||||
int64_t bandwidth_,
|
||||
int64_t sample_rate_,
|
||||
int64_t freq_,
|
||||
const std::string& rf_port_select_,
|
||||
const std::string& rf_filter,
|
||||
const std::string& gain_mode_rx0_,
|
||||
const std::string& gain_mode_rx1_,
|
||||
double rf_gain_rx0_,
|
||||
double rf_gain_rx1_,
|
||||
bool enable_ch0,
|
||||
bool enable_ch1,
|
||||
long long freq_2ch,
|
||||
int64_t freq_2ch,
|
||||
bool ppsmode_,
|
||||
bool customsamplesize_,
|
||||
std::string fe_ip_,
|
||||
const std::string& fe_ip_,
|
||||
int fe_ctlport_,
|
||||
int ssize_,
|
||||
int bshift_,
|
||||
@ -85,9 +86,10 @@ ad936x_iio_source_sptr ad936x_iio_make_source_sptr(
|
||||
tx_lo_channel_));
|
||||
}
|
||||
|
||||
void ad936x_iio_source::ad9361_channel_demux_and_record(ad936x_iio_samples *samples_in, int nchannels, std::vector<std::fstream> *files_out)
|
||||
|
||||
void ad936x_iio_source::ad9361_channel_demux_and_record(ad936x_iio_samples* samples_in, int nchannels, std::vector<std::fstream>* files_out)
|
||||
{
|
||||
int32_t current_byte = 0;
|
||||
uint32_t current_byte = 0;
|
||||
int16_t ch = 0;
|
||||
// std::cout << "nbytes: " << samples_in->n_bytes << " nsamples: " << samples_in->n_samples << " nch: " << nchannels << "\n";
|
||||
while (current_byte < samples_in->n_bytes)
|
||||
@ -101,24 +103,25 @@ void ad936x_iio_source::ad9361_channel_demux_and_record(ad936x_iio_samples *samp
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ad936x_iio_source::ad936x_iio_source(
|
||||
std::string pluto_uri_,
|
||||
std::string board_type_,
|
||||
long long bandwidth_,
|
||||
long long sample_rate_,
|
||||
long long freq_,
|
||||
std::string rf_port_select_,
|
||||
std::string rf_filter,
|
||||
std::string gain_mode_rx0_,
|
||||
std::string gain_mode_rx1_,
|
||||
const std::string& pluto_uri_,
|
||||
const std::string& board_type_,
|
||||
int64_t bandwidth_,
|
||||
int64_t sample_rate_,
|
||||
int64_t freq_,
|
||||
const std::string& rf_port_select_,
|
||||
const std::string& rf_filter,
|
||||
const std::string& gain_mode_rx0_,
|
||||
const std::string& gain_mode_rx1_,
|
||||
double rf_gain_rx0_,
|
||||
double rf_gain_rx1_,
|
||||
bool enable_ch0,
|
||||
bool enable_ch1,
|
||||
long long freq_2ch,
|
||||
int64_t freq_2ch,
|
||||
bool ppsmode_,
|
||||
bool customsamplesize_,
|
||||
std::string fe_ip_,
|
||||
const std::string& fe_ip_,
|
||||
int fe_ctlport_,
|
||||
int ssize_,
|
||||
int bshift_,
|
||||
@ -171,54 +174,81 @@ ad936x_iio_source::ad936x_iio_source(
|
||||
case 16:
|
||||
{
|
||||
std::cout << "FPGA sample size set to 16 bits per sample.\n";
|
||||
if (pps_rx->send_cmd("ssize=16\n") == false) std::cout << "cmd send error!\n";
|
||||
if (pps_rx->send_cmd("ssize=16\n") == false)
|
||||
{
|
||||
std::cout << "cmd send error!\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
std::cout << "FPGA sample size set to 8 bits per sample.\n";
|
||||
if (pps_rx->send_cmd("ssize=8\n") == false) std::cout << "cmd send error!\n";
|
||||
if (pps_rx->send_cmd("ssize=8\n") == false)
|
||||
{
|
||||
std::cout << "cmd send error!\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
std::cout << "FPGA sample size set to 4 bits per sample.\n";
|
||||
if (pps_rx->send_cmd("ssize=4\n") == false) std::cout << "cmd send error!\n";
|
||||
if (pps_rx->send_cmd("ssize=4\n") == false)
|
||||
{
|
||||
std::cout << "cmd send error!\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
std::cout << "FPGA sample size set to 2 bits per sample.\n";
|
||||
if (pps_rx->send_cmd("ssize=2\n") == false) std::cout << "cmd send error!\n";
|
||||
if (pps_rx->send_cmd("ssize=2\n") == false)
|
||||
{
|
||||
std::cout << "cmd send error!\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
std::cout << "WARNING: Unsupported ssize. FPGA sample size set to 16 bits per sample.\n";
|
||||
if (pps_rx->send_cmd("ssize=16") == false) std::cout << "cmd send error!\n";
|
||||
if (pps_rx->send_cmd("ssize=16") == false)
|
||||
{
|
||||
std::cout << "cmd send error!\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bshift_ >= 0 and bshift_ <= 14)
|
||||
{
|
||||
std::cout << "FPGA sample bits shift left set to " + std::to_string(bshift_) + " positions.\n";
|
||||
if (pps_rx->send_cmd("bshift=" + std::to_string(bshift_) + "\n") == false) std::cout << "cmd send error!\n";
|
||||
if (pps_rx->send_cmd("bshift=" + std::to_string(bshift_) + "\n") == false)
|
||||
{
|
||||
std::cout << "cmd send error!\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "WARNING: Unsupported bshift. FPGA sample bits shift left set to 0.\n";
|
||||
if (pps_rx->send_cmd("bshift=0\n") == false) std::cout << "cmd send error!\n";
|
||||
if (pps_rx->send_cmd("bshift=0\n") == false)
|
||||
{
|
||||
std::cout << "cmd send error!\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (spattern_ == true)
|
||||
{
|
||||
std::cout << "FPGA debug sample pattern is active!.\n";
|
||||
if (pps_rx->send_cmd("spattern=1\n") == false) std::cout << "cmd send error!\n";
|
||||
if (pps_rx->send_cmd("spattern=1\n") == false)
|
||||
{
|
||||
std::cout << "cmd send error!\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "FPGA debug sample pattern disabled.\n";
|
||||
if (pps_rx->send_cmd("spattern=0\n") == false) std::cout << "cmd send error!\n";
|
||||
if (pps_rx->send_cmd("spattern=0\n") == false)
|
||||
{
|
||||
std::cout << "cmd send error!\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -238,7 +268,7 @@ ad936x_iio_source::ad936x_iio_source(
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
catch (std::exception const &ex)
|
||||
catch (std::exception const& ex)
|
||||
{
|
||||
std::cerr << "STD exception: " << ex.what() << std::endl;
|
||||
exit(1);
|
||||
@ -267,6 +297,7 @@ ad936x_iio_source::ad936x_iio_source(
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
ad936x_iio_source::~ad936x_iio_source()
|
||||
{
|
||||
// Terminate PPS thread
|
||||
@ -284,6 +315,7 @@ bool ad936x_iio_source::start()
|
||||
return ad936x_custom->start_sample_rx(false);
|
||||
}
|
||||
|
||||
|
||||
bool ad936x_iio_source::stop()
|
||||
{
|
||||
std::cout << "stopping ad936x_iio_source...\n";
|
||||
@ -291,17 +323,17 @@ bool ad936x_iio_source::stop()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int ad936x_iio_source::general_work(int noutput_items,
|
||||
__attribute__((unused)) gr_vector_int &ninput_items,
|
||||
__attribute__((unused)) gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
__attribute__((unused)) gr_vector_int& ninput_items,
|
||||
__attribute__((unused)) gr_vector_const_void_star& input_items,
|
||||
gr_vector_void_star& output_items)
|
||||
{
|
||||
std::shared_ptr<ad936x_iio_samples> current_buffer;
|
||||
ad936x_iio_samples *current_samples;
|
||||
ad936x_iio_samples* current_samples;
|
||||
ad936x_custom->pop_sample_buffer(current_buffer);
|
||||
current_samples = current_buffer.get();
|
||||
|
||||
|
||||
// I and Q samples are interleaved in buffer: IQIQIQ...
|
||||
int32_t n_interleaved_iq_samples_per_channel = current_samples->n_bytes / (ad936x_custom->n_channels * 2);
|
||||
if (noutput_items < n_interleaved_iq_samples_per_channel)
|
||||
@ -312,7 +344,7 @@ int ad936x_iio_source::general_work(int noutput_items,
|
||||
else
|
||||
{
|
||||
// ad9361_channel_demux_and_record(current_samples, ad936x_custom->n_channels, &samplesfile);
|
||||
auto **out = reinterpret_cast<int8_t **>(&output_items[0]);
|
||||
auto** out = reinterpret_cast<int8_t**>(&output_items[0]);
|
||||
uint32_t current_byte = 0;
|
||||
uint32_t current_byte_in_gr = 0;
|
||||
int16_t ch = 0;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*!
|
||||
* \file ad936x_iio_source.h
|
||||
* \brief A direct IIO custom front-end gnss-sdr signal gnuradio block for the AD936x AD front-end family with special FPGA custom functionalities.
|
||||
* \brief A direct IIO custom front-end gnss-sdr signal gnuradio block for the
|
||||
* AD936x AD front-end family with special FPGA custom functionalities.
|
||||
* \author Javier Arribas, jarribas(at)cttc.es
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
@ -44,23 +45,23 @@ class ad936x_iio_source;
|
||||
using ad936x_iio_source_sptr = gnss_shared_ptr<ad936x_iio_source>;
|
||||
|
||||
ad936x_iio_source_sptr ad936x_iio_make_source_sptr(
|
||||
std::string pluto_uri_,
|
||||
std::string board_type_,
|
||||
long long bandwidth_,
|
||||
long long sample_rate_,
|
||||
long long freq_,
|
||||
std::string rf_port_select_,
|
||||
std::string rf_filter,
|
||||
std::string gain_mode_rx0_,
|
||||
std::string gain_mode_rx1_,
|
||||
const std::string &pluto_uri_,
|
||||
const std::string &board_type_,
|
||||
int64_t bandwidth_,
|
||||
int64_t sample_rate_,
|
||||
int64_t freq_,
|
||||
const std::string &rf_port_select_,
|
||||
const std::string &rf_filter,
|
||||
const std::string &gain_mode_rx0_,
|
||||
const std::string &gain_mode_rx1_,
|
||||
double rf_gain_rx0_,
|
||||
double rf_gain_rx1_,
|
||||
bool enable_ch0,
|
||||
bool enable_ch1,
|
||||
long long freq_2ch,
|
||||
int64_t freq_2ch,
|
||||
bool ppsmode_,
|
||||
bool customsamplesize_,
|
||||
std::string fe_ip_,
|
||||
const std::string &fe_ip_,
|
||||
int fe_ctlport_,
|
||||
int ssize_,
|
||||
int bshift_,
|
||||
@ -90,23 +91,23 @@ public:
|
||||
|
||||
private:
|
||||
friend ad936x_iio_source_sptr ad936x_iio_make_source_sptr(
|
||||
std::string pluto_uri_,
|
||||
std::string board_type_,
|
||||
long long bandwidth_,
|
||||
long long sample_rate_,
|
||||
long long freq_,
|
||||
std::string rf_port_select_,
|
||||
std::string rf_filter,
|
||||
std::string gain_mode_rx0_,
|
||||
std::string gain_mode_rx1_,
|
||||
const std::string &pluto_uri_,
|
||||
const std::string &board_type_,
|
||||
int64_t bandwidth_,
|
||||
int64_t sample_rate_,
|
||||
int64_t freq_,
|
||||
const std::string &rf_port_select_,
|
||||
const std::string &rf_filter,
|
||||
const std::string &gain_mode_rx0_,
|
||||
const std::string &gain_mode_rx1_,
|
||||
double rf_gain_rx0_,
|
||||
double rf_gain_rx1_,
|
||||
bool enable_ch0,
|
||||
bool enable_ch1,
|
||||
long long freq_2ch,
|
||||
int64_t freq_2ch,
|
||||
bool ppsmode_,
|
||||
bool customsamplesize_,
|
||||
std::string fe_ip_,
|
||||
const std::string &fe_ip_,
|
||||
int fe_ctlport_,
|
||||
int ssize_,
|
||||
int bshift_,
|
||||
@ -116,23 +117,23 @@ private:
|
||||
int tx_lo_channel_);
|
||||
|
||||
ad936x_iio_source(
|
||||
std::string pluto_uri_,
|
||||
std::string board_type_,
|
||||
long long bandwidth_,
|
||||
long long sample_rate_,
|
||||
long long freq_,
|
||||
std::string rf_port_select_,
|
||||
std::string rf_filter,
|
||||
std::string gain_mode_rx0_,
|
||||
std::string gain_mode_rx1_,
|
||||
const std::string &pluto_uri_,
|
||||
const std::string &board_type_,
|
||||
int64_t bandwidth_,
|
||||
int64_t sample_rate_,
|
||||
int64_t freq_,
|
||||
const std::string &rf_port_select_,
|
||||
const std::string &rf_filter,
|
||||
const std::string &gain_mode_rx0_,
|
||||
const std::string &gain_mode_rx1_,
|
||||
double rf_gain_rx0_,
|
||||
double rf_gain_rx1_,
|
||||
bool enable_ch0,
|
||||
bool enable_ch1,
|
||||
long long freq_2ch,
|
||||
int64_t freq_2ch,
|
||||
bool ppsmode_,
|
||||
bool customsamplesize_,
|
||||
std::string fe_ip_,
|
||||
const std::string &fe_ip_,
|
||||
int fe_ctlport_,
|
||||
int ssize_,
|
||||
int bshift_,
|
||||
@ -141,7 +142,6 @@ private:
|
||||
bool high_side_lo_,
|
||||
int tx_lo_channel_);
|
||||
|
||||
|
||||
void ad9361_channel_demux_to_buffer(ad936x_iio_samples *samples_in, int nchannels, gr_vector_void_star &output_items);
|
||||
void ad9361_channel_demux_and_record(ad936x_iio_samples *samples_in, int nchannels, std::vector<std::fstream> *files_out);
|
||||
|
||||
|
202
src/algorithms/signal_source/gnuradio_blocks/ion_gsms.cc
Normal file
202
src/algorithms/signal_source/gnuradio_blocks/ion_gsms.cc
Normal file
@ -0,0 +1,202 @@
|
||||
/*!
|
||||
* \file ion_gsms.cc
|
||||
* \brief GNU Radio block that reads a Block from a file following ION's GNSS-SDR metadata standard
|
||||
* \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* 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 "ion_gsms.h"
|
||||
#include "gnuradio/block.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#if USE_GLOG_AND_GFLAGS
|
||||
#include <glog/logging.h>
|
||||
#else
|
||||
#include <absl/log/log.h>
|
||||
#endif
|
||||
|
||||
IONGSMSFileSource::IONGSMSFileSource(
|
||||
const fs::path& metadata_filepath,
|
||||
const GnssMetadata::File& file,
|
||||
const GnssMetadata::Block& block,
|
||||
const std::vector<std::string>& stream_ids)
|
||||
: gr::sync_block(
|
||||
"ion_gsms_file_source",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
make_output_signature(block, stream_ids)),
|
||||
file_stream_(metadata_filepath.parent_path() / file.Url().Value(), std::ios::in | std::ios::binary),
|
||||
io_buffer_offset_(0),
|
||||
maximum_item_rate_(0),
|
||||
chunk_cycle_length_(0)
|
||||
{
|
||||
fs::path data_filepath = metadata_filepath.parent_path() / file.Url().Value();
|
||||
std::size_t block_offset = file.Offset();
|
||||
|
||||
if (!file_stream_.is_open())
|
||||
{
|
||||
LOG(WARNING) << "ION_GSMS_Signal_Source - Unable to open the samples file: " << (data_filepath).c_str();
|
||||
std::cerr << "ION_GSMS_Signal_Source - Unable to open the samples file: " << (data_filepath).c_str() << std::endl;
|
||||
std::cout << "GNSS-SDR program ended.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Skip offset and block header
|
||||
file_stream_.seekg(file.Offset() + block_offset + block.SizeHeader());
|
||||
|
||||
std::size_t output_stream_offset = 0;
|
||||
for (const auto& chunk : block.Chunks())
|
||||
{
|
||||
chunk_data_.emplace_back(std::make_shared<IONGSMSChunkData>(chunk, stream_ids, output_stream_offset));
|
||||
chunk_cycle_length_ += chunk.CountWords() * chunk.SizeWord();
|
||||
const std::size_t out_count = chunk_data_.back()->output_stream_count();
|
||||
output_stream_offset += out_count;
|
||||
for (std::size_t i = 0; i < out_count; ++i)
|
||||
{
|
||||
output_stream_item_sizes_.push_back(chunk_data_.back()->output_stream_item_size(i));
|
||||
output_stream_item_rates_.push_back(chunk_data_.back()->output_stream_item_rate(i));
|
||||
maximum_item_rate_ = std::max(chunk_data_.back()->output_stream_item_rate(i), maximum_item_rate_);
|
||||
}
|
||||
}
|
||||
output_stream_count_ = output_stream_offset;
|
||||
|
||||
output_stream_total_sample_counts_.resize(output_stream_count_);
|
||||
|
||||
std::size_t cycle_count = block.Cycles();
|
||||
if (cycle_count == 0)
|
||||
{
|
||||
// Read the whole file
|
||||
const std::size_t file_size = fs::file_size(data_filepath);
|
||||
cycle_count = std::floor((file_size - block_offset - block.SizeHeader()) / chunk_cycle_length_);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < output_stream_count_; ++i)
|
||||
{
|
||||
output_stream_total_sample_counts_[i] = cycle_count * output_stream_item_rates_[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::size_t IONGSMSFileSource::output_stream_count() const
|
||||
{
|
||||
return output_stream_count_;
|
||||
}
|
||||
|
||||
|
||||
std::size_t IONGSMSFileSource::output_stream_item_size(std::size_t stream_index) const
|
||||
{
|
||||
return output_stream_item_sizes_[stream_index];
|
||||
}
|
||||
|
||||
|
||||
std::size_t IONGSMSFileSource::output_stream_total_sample_count(std::size_t stream_index) const
|
||||
{
|
||||
return output_stream_total_sample_counts_[stream_index];
|
||||
}
|
||||
|
||||
|
||||
gr::io_signature::sptr IONGSMSFileSource::make_output_signature(const GnssMetadata::Block& block, const std::vector<std::string>& stream_ids)
|
||||
{
|
||||
int nstreams = 0;
|
||||
std::vector<int> item_sizes{};
|
||||
|
||||
for (const auto& chunk : block.Chunks())
|
||||
{
|
||||
for (const auto& lump : chunk.Lumps())
|
||||
{
|
||||
for (const auto& stream : lump.Streams())
|
||||
{
|
||||
bool found = false;
|
||||
for (const auto& stream_id : stream_ids)
|
||||
{
|
||||
if (stream_id == stream.Id())
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
++nstreams;
|
||||
std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor();
|
||||
if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization())
|
||||
{
|
||||
// Samples have 'Complex' format
|
||||
sample_bitsize /= 2;
|
||||
}
|
||||
item_sizes.push_back(bits_to_item_size(sample_bitsize));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gr::io_signature::makev(
|
||||
nstreams,
|
||||
nstreams,
|
||||
item_sizes);
|
||||
}
|
||||
|
||||
|
||||
int IONGSMSFileSource::work(
|
||||
int noutput_items,
|
||||
gr_vector_const_void_star& input_items __attribute__((unused)),
|
||||
gr_vector_void_star& output_items)
|
||||
{
|
||||
// Compute the maximum number of samples that will be copied across all output buffer.
|
||||
// If there are more than one output buffer (multichannel set up), the one with the most samples will be used as the maximum.
|
||||
//
|
||||
// Complex samples produce 2 items each (I and Q). In order to account for them, we subtract 1 from `noutput_items` and
|
||||
// then floor the division. During testing, not doing this caused `max_sample_output` to oscillate between two values, thus
|
||||
// resizing the `io_buffer_` on each call to `work()`.
|
||||
const std::size_t max_sample_output = std::floor((noutput_items - 1.0) / maximum_item_rate_);
|
||||
|
||||
// Resize the IO buffer to fit exactly the maximum amount of samples that will be outputted.
|
||||
io_buffer_.resize(max_sample_output * chunk_cycle_length_);
|
||||
|
||||
// We will be walking the IO buffer with this variable.
|
||||
io_buffer_offset_ = 0;
|
||||
|
||||
// Read samples from file into IO buffer
|
||||
const std::size_t bytes_to_read = io_buffer_.size();
|
||||
file_stream_.read(io_buffer_.data(), bytes_to_read);
|
||||
|
||||
// Reset `items_produced_` vector. This vector will accumulate the amount of items produced for each output stream.
|
||||
items_produced_.clear();
|
||||
items_produced_.resize(output_items.size());
|
||||
|
||||
// Walk the IO buffer one chunk cycle at a time. See ION documentation for a definition of chunk and chunk cycle.
|
||||
while (io_buffer_offset_ < bytes_to_read)
|
||||
{
|
||||
// Iterate chunks within a chunk cycle
|
||||
for (auto& chunk : chunk_data_)
|
||||
{
|
||||
// Copy chunk into a separate buffer where the samples will be shifted from.
|
||||
const std::size_t bytes_copied = chunk->read_from_buffer(reinterpret_cast<uint8_t*>(io_buffer_.data()), io_buffer_offset_);
|
||||
|
||||
// Advance IO buffer offset
|
||||
io_buffer_offset_ += bytes_copied;
|
||||
|
||||
// Shift samples into output buffers following the appropriate unpacking strategy for this chunk.
|
||||
chunk->write_to_output(output_items, items_produced_);
|
||||
}
|
||||
}
|
||||
|
||||
// Call `produce(int, int)` with the appropriate item count for each output stream.
|
||||
for (std::size_t i = 0; i < items_produced_.size(); ++i)
|
||||
{
|
||||
produce(i, items_produced_[i]);
|
||||
}
|
||||
|
||||
return WORK_CALLED_PRODUCE;
|
||||
}
|
74
src/algorithms/signal_source/gnuradio_blocks/ion_gsms.h
Normal file
74
src/algorithms/signal_source/gnuradio_blocks/ion_gsms.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*!
|
||||
* \file ion_gsms.h
|
||||
* \brief GNU Radio block that reads a Block from a file following ION's GNSS-SDR metadata standard
|
||||
* \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* 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_ION_GSMS_H
|
||||
#define GNSS_SDR_ION_GSMS_H
|
||||
|
||||
#include "gnss_block_interface.h"
|
||||
#include "gnss_sdr_filesystem.h"
|
||||
#include "ion_gsms_chunk_data.h"
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
#include <cstddef>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
* \{ */
|
||||
/** \addtogroup Signal_Source_gnuradio_blocks
|
||||
* \{ */
|
||||
|
||||
class IONGSMSFileSource : public gr::sync_block
|
||||
{
|
||||
public:
|
||||
using sptr = gnss_shared_ptr<IONGSMSFileSource>;
|
||||
|
||||
IONGSMSFileSource(
|
||||
const fs::path& metadata_filepath,
|
||||
const GnssMetadata::File& file,
|
||||
const GnssMetadata::Block& block,
|
||||
const std::vector<std::string>& stream_ids);
|
||||
|
||||
int work(
|
||||
int noutput_items,
|
||||
gr_vector_const_void_star& input_items,
|
||||
gr_vector_void_star& output_items) override;
|
||||
|
||||
std::size_t output_stream_count() const;
|
||||
std::size_t output_stream_item_size(std::size_t stream_index) const;
|
||||
std::size_t output_stream_total_sample_count(std::size_t stream_index) const;
|
||||
|
||||
private:
|
||||
static gr::io_signature::sptr make_output_signature(const GnssMetadata::Block& block, const std::vector<std::string>& stream_ids);
|
||||
|
||||
std::ifstream file_stream_;
|
||||
std::vector<char> io_buffer_;
|
||||
std::size_t io_buffer_offset_;
|
||||
std::vector<int> items_produced_;
|
||||
std::size_t output_stream_count_;
|
||||
std::vector<std::size_t> output_stream_item_sizes_;
|
||||
std::vector<std::size_t> output_stream_item_rates_;
|
||||
std::vector<std::size_t> output_stream_total_sample_counts_;
|
||||
std::size_t maximum_item_rate_;
|
||||
std::vector<std::shared_ptr<IONGSMSChunkData>> chunk_data_;
|
||||
std::size_t chunk_cycle_length_;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_ION_GSMS_H
|
@ -7,14 +7,15 @@
|
||||
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES "")
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS "")
|
||||
|
||||
if(ENABLE_FMCOMMS2 OR ENABLE_AD9361)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad9361_manager.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad9361_manager.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ad9361_manager.h)
|
||||
endif()
|
||||
|
||||
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)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_spidev.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FPGA)
|
||||
@ -34,16 +35,21 @@ if((ENABLE_FPGA AND ENABLE_AD9361) OR ENABLE_MAX2771)
|
||||
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)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_samples.h)
|
||||
if(ENABLE_PLUTOSDR OR ENABLE_AD936X_SDR)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ad936x_iio_samples.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_custom.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_custom.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} pps_samplestamp.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ad936x_iio_custom.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} pps_samplestamp.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ppstcprx.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ppstcprx.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ppstcprx.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ION)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms_chunk_data.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_data.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_stream_encodings.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_unpacking_ctx.h)
|
||||
endif()
|
||||
|
||||
set(SIGNAL_SOURCE_LIB_SOURCES
|
||||
rtl_tcp_commands.cc
|
||||
@ -107,7 +113,7 @@ if(GNURADIO_USES_STD_POINTERS)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FMCOMMS2 OR ENABLE_AD9361 OR ENABLE_PLUTOSDR)
|
||||
if(ENABLE_FMCOMMS2 OR ENABLE_AD9361 OR ENABLE_PLUTOSDR OR ENABLE_AD936X_SDR)
|
||||
target_link_libraries(signal_source_libs
|
||||
PUBLIC
|
||||
Iio::iio
|
||||
@ -130,6 +136,10 @@ if(ENABLE_FPGA OR ENABLE_AD9361)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ION)
|
||||
target_link_libraries(signal_source_libs PUBLIC ION::ion algorithms_libs)
|
||||
endif()
|
||||
|
||||
if(ENABLE_CLANG_TIDY)
|
||||
if(CLANG_TIDY_EXE)
|
||||
set_target_properties(signal_source_libs
|
||||
|
@ -349,7 +349,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_,
|
||||
#ifndef LIBAD9361_VERSION_GREATER_THAN_01
|
||||
if (filter_source_ == "Design")
|
||||
{
|
||||
std::cout << "Option filter_source=Design is not available in this version. Set to filter_source=Off\n";
|
||||
std::cout << "Option filter_source=Design is not available in this version of libad9361. Set to filter_source=Off\n";
|
||||
filter_source_ = std::string("Off");
|
||||
}
|
||||
if (Fpass_ != 0.0 or Fstop_ != 0.0)
|
||||
@ -636,7 +636,7 @@ bool config_ad9361_rx_remote(const std::string &remote_host,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (setup_filter(std::move(filter_source_), bandwidth_, sample_rate_, freq_, rf_port_select_, ad9361_phy, rx_chan0, chn, 0, std::move(filter_filename_), Fpass_, Fstop_) == -1)
|
||||
if (setup_filter(filter_source_, bandwidth_, sample_rate_, freq_, rf_port_select_, ad9361_phy, rx_chan0, chn, 0, std::move(filter_filename_), Fpass_, Fstop_) == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*!
|
||||
* \file ad936x_iio_custom.cc
|
||||
* \brief A direct IIO custom front-end driver for the AD936x AD front-end family with special FPGA custom functionalities.
|
||||
* \brief A direct IIO custom front-end driver for the AD936x AD front-end
|
||||
* family with special FPGA custom functionalities.
|
||||
* \author Javier Arribas, jarribas(at)cttc.es
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
@ -30,29 +31,36 @@
|
||||
#include <absl/log/log.h>
|
||||
#endif
|
||||
|
||||
ad936x_iio_custom::ad936x_iio_custom(int debug_level_, int log_level_)
|
||||
ad936x_iio_custom::ad936x_iio_custom(
|
||||
int debug_level_,
|
||||
int log_level_) : n_channels(0),
|
||||
ctx(nullptr),
|
||||
phy(nullptr),
|
||||
stream_dev(nullptr),
|
||||
dds_dev(nullptr),
|
||||
receive_samples(false),
|
||||
fpga_overflow(false),
|
||||
sample_rate_sps(0),
|
||||
debug_level(debug_level_),
|
||||
log_level(log_level_),
|
||||
PPS_mode(false)
|
||||
{
|
||||
receive_samples = false;
|
||||
fpga_overflow = false;
|
||||
sample_rate_sps = 0;
|
||||
ctx = NULL;
|
||||
phy = NULL;
|
||||
dds_dev = NULL;
|
||||
stream_dev = NULL;
|
||||
debug_level = debug_level_;
|
||||
log_level = log_level_;
|
||||
PPS_mode = false;
|
||||
n_channels = 0;
|
||||
}
|
||||
|
||||
|
||||
ad936x_iio_custom::~ad936x_iio_custom()
|
||||
{
|
||||
// disable TX
|
||||
if (phy != NULL) PlutoTxEnable(false);
|
||||
if (phy != nullptr)
|
||||
{
|
||||
PlutoTxEnable(false);
|
||||
}
|
||||
|
||||
// Close device
|
||||
if (ctx != NULL) iio_context_destroy(ctx);
|
||||
if (ctx != nullptr)
|
||||
{
|
||||
iio_context_destroy(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -68,7 +76,7 @@ void ad936x_iio_custom::set_pps_samplestamp_queue(std::shared_ptr<Concurrent_Que
|
||||
}
|
||||
|
||||
|
||||
bool ad936x_iio_custom::initialize_device(std::string pluto_device_uri, std::string board_type)
|
||||
bool ad936x_iio_custom::initialize_device(const std::string &pluto_device_uri, const std::string &board_type)
|
||||
{
|
||||
// Find devices
|
||||
if (pluto_device_uri == "local")
|
||||
@ -123,7 +131,7 @@ bool ad936x_iio_custom::initialize_device(std::string pluto_device_uri, std::str
|
||||
ctx = iio_create_context_from_uri(pluto_device_uri.c_str());
|
||||
}
|
||||
|
||||
if (ctx == NULL)
|
||||
if (ctx == nullptr)
|
||||
{
|
||||
std::cout << "Unable to create context from uri: " << pluto_device_uri << std::endl;
|
||||
return false;
|
||||
@ -131,16 +139,16 @@ bool ad936x_iio_custom::initialize_device(std::string pluto_device_uri, std::str
|
||||
|
||||
phy = iio_context_find_device(ctx, "ad9361-phy");
|
||||
|
||||
if (phy == NULL)
|
||||
if (phy == nullptr)
|
||||
{
|
||||
std::cout << "Unable to find ad9361-phy device from uri: " << pluto_device_uri << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (board_type.compare("fmcomms5") == 0)
|
||||
if (board_type == "fmcomms5")
|
||||
{
|
||||
stream_dev = iio_context_find_device(ctx, "cf-ad9361-A"); // first ad9361 in FMCOMMS5
|
||||
if (stream_dev == NULL)
|
||||
if (stream_dev == nullptr)
|
||||
{
|
||||
std::cout << "Unable to find cf-ad9361-A device from uri: " << pluto_device_uri << std::endl;
|
||||
return false;
|
||||
@ -149,13 +157,13 @@ bool ad936x_iio_custom::initialize_device(std::string pluto_device_uri, std::str
|
||||
else
|
||||
{
|
||||
stream_dev = iio_context_find_device(ctx, "cf-ad9361-lpc"); // regular AD9361 stream device in single AD9361 boards
|
||||
if (stream_dev == NULL)
|
||||
if (stream_dev == nullptr)
|
||||
{
|
||||
std::cout << "Unable to find cf-ad9361-lpc device from uri: " << pluto_device_uri << std::endl;
|
||||
return false;
|
||||
};
|
||||
dds_dev = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc"); // DDS core for LO oscillator (external transverter operation)
|
||||
if (stream_dev == NULL)
|
||||
if (stream_dev == nullptr)
|
||||
{
|
||||
std::cout << "Warning: Unable to find cf-ad9361-dds-core-lpc device from uri: " << pluto_device_uri << std::endl;
|
||||
};
|
||||
@ -168,23 +176,22 @@ bool ad936x_iio_custom::initialize_device(std::string pluto_device_uri, std::str
|
||||
void ad936x_iio_custom::configure_params(struct iio_device *phy,
|
||||
const std::vector<std::string> ¶ms)
|
||||
{
|
||||
for (std::vector<std::string>::const_iterator it = params.begin();
|
||||
it != params.end(); ++it)
|
||||
for (const auto ¶m : params)
|
||||
{
|
||||
struct iio_channel *chn = NULL;
|
||||
const char *attr = NULL;
|
||||
struct iio_channel *chn = nullptr;
|
||||
const char *attr = nullptr;
|
||||
size_t pos;
|
||||
int ret;
|
||||
|
||||
pos = it->find('=');
|
||||
pos = param.find('=');
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
std::cerr << "Malformed line: " << *it << std::endl;
|
||||
std::cerr << "Malformed line: " << param << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string key = it->substr(0, pos);
|
||||
std::string val = it->substr(pos + 1, std::string::npos);
|
||||
std::string key = param.substr(0, pos);
|
||||
std::string val = param.substr(pos + 1, std::string::npos);
|
||||
|
||||
ret = iio_device_identify_filename(phy,
|
||||
key.c_str(), &chn, &attr);
|
||||
@ -196,13 +203,19 @@ void ad936x_iio_custom::configure_params(struct iio_device *phy,
|
||||
}
|
||||
|
||||
if (chn)
|
||||
ret = iio_channel_attr_write(chn,
|
||||
attr, val.c_str());
|
||||
{
|
||||
ret = iio_channel_attr_write(chn,
|
||||
attr, val.c_str());
|
||||
}
|
||||
else if (iio_device_find_attr(phy, attr))
|
||||
ret = iio_device_attr_write(phy, attr, val.c_str());
|
||||
{
|
||||
ret = iio_device_attr_write(phy, attr, val.c_str());
|
||||
}
|
||||
else
|
||||
ret = iio_device_debug_attr_write(phy,
|
||||
attr, val.c_str());
|
||||
{
|
||||
ret = iio_device_debug_attr_write(phy,
|
||||
attr, val.c_str());
|
||||
}
|
||||
if (ret < 0)
|
||||
{
|
||||
std::cerr << "Unable to write attribute " << key
|
||||
@ -216,9 +229,9 @@ void ad936x_iio_custom::set_params_rx(struct iio_device *phy_device,
|
||||
unsigned long long frequency,
|
||||
unsigned long samplerate, unsigned long bandwidth,
|
||||
bool quadrature, bool rfdc, bool bbdc,
|
||||
std::string gain1, double gain1_value,
|
||||
std::string gain2, double gain2_value,
|
||||
std::string port_select)
|
||||
const std::string &gain1, double gain1_value,
|
||||
const std::string &gain2, double gain2_value,
|
||||
const std::string &port_select)
|
||||
{
|
||||
std::vector<std::string> params;
|
||||
|
||||
@ -289,7 +302,7 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_,
|
||||
std::to_string(phase_dds_deg_ * 1000.0));
|
||||
params_dds.push_back("out_altvoltage0_TX1_I_F1_scale=" +
|
||||
std::to_string(scale_dds_));
|
||||
params_dds.push_back("out_altvoltage0_TX1_I_F1_raw=1");
|
||||
params_dds.emplace_back("out_altvoltage0_TX1_I_F1_raw=1");
|
||||
// DDS TX CH1 Q (tone #1)
|
||||
params_dds.push_back("out_altvoltage2_TX1_Q_F1_frequency=" +
|
||||
std::to_string(freq_dds_tx_hz_));
|
||||
@ -297,7 +310,7 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_,
|
||||
std::to_string(phase_dds_deg_ * 1000.0 + 270000.0));
|
||||
params_dds.push_back("out_altvoltage2_TX1_Q_F1_scale=" +
|
||||
std::to_string(scale_dds_));
|
||||
params_dds.push_back("out_altvoltage2_TX1_Q_F1_raw=1");
|
||||
params_dds.emplace_back("out_altvoltage2_TX1_Q_F1_raw=1");
|
||||
|
||||
configure_params(dds_dev, params_dds);
|
||||
}
|
||||
@ -318,7 +331,7 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_,
|
||||
std::to_string(phase_dds_deg_ * 1000.0));
|
||||
params_dds.push_back("out_altvoltage4_TX2_I_F1_scale=" +
|
||||
std::to_string(scale_dds_));
|
||||
params_dds.push_back("out_altvoltage4_TX2_I_F1_raw=1");
|
||||
params_dds.emplace_back("out_altvoltage4_TX2_I_F1_raw=1");
|
||||
// DDS TX CH2 Q (tone #1)
|
||||
params_dds.push_back("out_altvoltage6_TX2_Q_F1_frequency=" +
|
||||
std::to_string(freq_dds_tx_hz_));
|
||||
@ -326,7 +339,7 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_,
|
||||
std::to_string(phase_dds_deg_ * 1000.0 + 270000.0));
|
||||
params_dds.push_back("out_altvoltage6_TX2_Q_F1_scale=" +
|
||||
std::to_string(scale_dds_));
|
||||
params_dds.push_back("out_altvoltage6_TX2_Q_F1_raw=1");
|
||||
params_dds.emplace_back("out_altvoltage6_TX2_Q_F1_raw=1");
|
||||
|
||||
configure_params(dds_dev, params_dds);
|
||||
}
|
||||
@ -337,7 +350,7 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_,
|
||||
|
||||
bool ad936x_iio_custom::check_device()
|
||||
{
|
||||
if (stream_dev != NULL)
|
||||
if (stream_dev != nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -350,8 +363,8 @@ bool ad936x_iio_custom::check_device()
|
||||
|
||||
bool ad936x_iio_custom::get_iio_param(iio_device *dev, const std::string ¶m, std::string &value)
|
||||
{
|
||||
struct iio_channel *chn = 0;
|
||||
const char *attr = 0;
|
||||
struct iio_channel *chn = nullptr;
|
||||
const char *attr = nullptr;
|
||||
char valuestr[256];
|
||||
int ret;
|
||||
ssize_t nchars;
|
||||
@ -398,9 +411,12 @@ bool ad936x_iio_custom::read_die_temp(double &temp_c)
|
||||
{
|
||||
try
|
||||
{
|
||||
uint32_t temp_mC = boost::lexical_cast<uint32_t>(temp_mC_str);
|
||||
auto temp_mC = boost::lexical_cast<uint32_t>(temp_mC_str);
|
||||
temp_c = static_cast<double>(temp_mC) / 1000.0;
|
||||
if (temp_c > 120) temp_c = -1;
|
||||
if (temp_c > 120)
|
||||
{
|
||||
temp_c = -1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (const boost::bad_lexical_cast &e)
|
||||
@ -419,10 +435,10 @@ bool ad936x_iio_custom::read_die_temp(double &temp_c)
|
||||
bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
|
||||
long long sample_rate_,
|
||||
long long freq_,
|
||||
std::string rf_port_select_,
|
||||
std::string rf_filter,
|
||||
std::string gain_mode_rx0_,
|
||||
std::string gain_mode_rx1_,
|
||||
const std::string &rf_port_select_,
|
||||
const std::string &rf_filter,
|
||||
const std::string &gain_mode_rx0_,
|
||||
const std::string &gain_mode_rx1_,
|
||||
double rf_gain_rx0_,
|
||||
double rf_gain_rx1_,
|
||||
bool enable_ch0,
|
||||
@ -432,16 +448,19 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
|
||||
bool high_side_lo_,
|
||||
int tx_lo_channel_)
|
||||
{
|
||||
if (check_device() == false) return false;
|
||||
if (check_device() == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool no_errors = true;
|
||||
std::cout << "Configuring phy device parameters...\n";
|
||||
int ret;
|
||||
if (rf_filter.compare("Disabled") == 0)
|
||||
if (rf_filter == "Disabled")
|
||||
{
|
||||
std::cout << "LNA Filter switch is disabled.\n";
|
||||
}
|
||||
else if (rf_filter.compare("Auto") == 0)
|
||||
else if (rf_filter == "Auto")
|
||||
{
|
||||
std::cout << "Selecting LNA RF filter based on the selected RF frequency... \n";
|
||||
if (freq_ == 1575420000)
|
||||
@ -498,9 +517,9 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
|
||||
params.push_back("out_voltage_rf_bandwidth=" +
|
||||
std::to_string(bandwidth_));
|
||||
|
||||
params.push_back("in_voltage_quadrature_tracking_en=1");
|
||||
params.push_back("in_voltage_rf_dc_offset_tracking_en=1");
|
||||
params.push_back("in_voltage_bb_dc_offset_tracking_en=1");
|
||||
params.emplace_back("in_voltage_quadrature_tracking_en=1");
|
||||
params.emplace_back("in_voltage_rf_dc_offset_tracking_en=1");
|
||||
params.emplace_back("in_voltage_bb_dc_offset_tracking_en=1");
|
||||
|
||||
configure_params(phy, params);
|
||||
|
||||
@ -705,7 +724,10 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
|
||||
|
||||
bool ad936x_iio_custom::set_rx_frequency(long long freq_hz)
|
||||
{
|
||||
if (check_device() == false) return false;
|
||||
if (check_device() == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Configure RX LO channel (NOTICE that altvoltage0 is the RX LO oscillator!, altvoltage1 is the TX oscillator)
|
||||
struct iio_channel *lo_ch;
|
||||
|
||||
@ -728,7 +750,10 @@ bool ad936x_iio_custom::set_rx_frequency(long long freq_hz)
|
||||
|
||||
bool ad936x_iio_custom::get_rx_frequency(long long &freq_hz)
|
||||
{
|
||||
if (check_device() == false) return false;
|
||||
if (check_device() == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Configure RX LO channel (NOTICE that altvoltage0 is the RX LO oscillator!, altvoltage1 is the TX oscillator)
|
||||
struct iio_channel *lo_ch;
|
||||
|
||||
@ -749,9 +774,12 @@ bool ad936x_iio_custom::get_rx_frequency(long long &freq_hz)
|
||||
}
|
||||
|
||||
|
||||
bool ad936x_iio_custom::setRXGain(int ch_num, std::string gain_mode, double gain_dB)
|
||||
bool ad936x_iio_custom::setRXGain(int ch_num, const std::string &gain_mode, double gain_dB)
|
||||
{
|
||||
if (check_device() == false) return false;
|
||||
if (check_device() == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::vector<std::string> params;
|
||||
if (ch_num == 0)
|
||||
{
|
||||
@ -784,7 +812,10 @@ 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;
|
||||
if (check_device() == false)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
double gain_dB; // gain in dB
|
||||
int ret = 0;
|
||||
if (ch_num == 0)
|
||||
@ -815,7 +846,10 @@ double ad936x_iio_custom::get_rx_gain(int ch_num)
|
||||
|
||||
bool ad936x_iio_custom::calibrate([[maybe_unused]] int ch, [[maybe_unused]] double bw_hz)
|
||||
{
|
||||
if (check_device() == false) return false;
|
||||
if (check_device() == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// todo
|
||||
return true;
|
||||
}
|
||||
@ -864,12 +898,13 @@ void ad936x_iio_custom::monitor_thread_fn()
|
||||
{
|
||||
ret = iio_device_reg_write(stream_dev, 0x80000088, val);
|
||||
if (ret)
|
||||
fprintf(stderr, "Failed to clearn DMA status register: %s\n",
|
||||
strerror(-ret));
|
||||
{
|
||||
fprintf(stderr, "Failed to clearn DMA status register: %s\n",
|
||||
strerror(-ret));
|
||||
}
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -940,7 +975,7 @@ void ad936x_iio_custom::setPlutoGpo(int p)
|
||||
}
|
||||
|
||||
|
||||
bool ad936x_iio_custom::select_rf_filter(std::string rf_filter)
|
||||
bool ad936x_iio_custom::select_rf_filter(const std::string &rf_filter)
|
||||
{
|
||||
// adi,gpo-manual-mode-enable Enables GPO manual mode, this will conflict with automatic ENSM slave and eLNA mode
|
||||
// adi,gpo-manual-mode-enable-mask Enable bit mask, setting or clearing bits will change the level of the corresponding output. Bit0 → GPO, Bit1 → GPO1, Bit2 → GPO2, Bit3 → GP03
|
||||
@ -960,7 +995,10 @@ 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;
|
||||
if (check_device() == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// int plutoGpo = 0;
|
||||
int ret;
|
||||
ret = iio_device_debug_attr_write(phy, "adi,gpo-manual-mode-enable", "1");
|
||||
@ -971,7 +1009,7 @@ bool ad936x_iio_custom::select_rf_filter(std::string rf_filter)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rf_filter.compare("E1") == 0)
|
||||
if (rf_filter == "E1")
|
||||
{
|
||||
// set gpio0 to switch L1 filter
|
||||
// setPlutoGpo(plutoGpo);
|
||||
@ -982,7 +1020,7 @@ bool ad936x_iio_custom::select_rf_filter(std::string rf_filter)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (rf_filter.compare("E5E6") == 0)
|
||||
else if (rf_filter == "E5E6")
|
||||
{
|
||||
// set gpio0 to switch L5/L6 filter (GPO0)
|
||||
// plutoGpo = plutoGpo | 0x10;
|
||||
@ -994,7 +1032,7 @@ bool ad936x_iio_custom::select_rf_filter(std::string rf_filter)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (rf_filter.compare("none") == 0)
|
||||
if (rf_filter == "none")
|
||||
{
|
||||
std::cout << "RF external filter not selected\n";
|
||||
}
|
||||
@ -1107,18 +1145,18 @@ bool ad936x_iio_custom::start_sample_rx(bool ppsmode)
|
||||
switch (n_channels)
|
||||
{
|
||||
case 1:
|
||||
channels.push_back("voltage0"); // Channel 0 I
|
||||
channels.push_back("voltage1"); // Channel 0 Q
|
||||
channels.emplace_back("voltage0"); // Channel 0 I
|
||||
channels.emplace_back("voltage1"); // Channel 0 Q
|
||||
break;
|
||||
case 2:
|
||||
channels.push_back("voltage0"); // Channel 0 I
|
||||
channels.push_back("voltage1"); // Channel 0 Q
|
||||
channels.push_back("voltage2"); // Channel 1 I
|
||||
channels.push_back("voltage3"); // Channel 1 Q
|
||||
channels.emplace_back("voltage0"); // Channel 0 I
|
||||
channels.emplace_back("voltage1"); // Channel 0 Q
|
||||
channels.emplace_back("voltage2"); // Channel 1 I
|
||||
channels.emplace_back("voltage3"); // Channel 1 Q
|
||||
break;
|
||||
default:
|
||||
channels.push_back("voltage0"); // Channel 0 I
|
||||
channels.push_back("voltage1"); // Channel 0 Q
|
||||
channels.emplace_back("voltage0"); // Channel 0 I
|
||||
channels.emplace_back("voltage1"); // Channel 0 Q
|
||||
}
|
||||
|
||||
receive_samples = true;
|
||||
@ -1150,7 +1188,10 @@ void ad936x_iio_custom::push_sample_buffer(std::shared_ptr<ad936x_iio_samples> &
|
||||
|
||||
void ad936x_iio_custom::capture(const std::vector<std::string> &channels)
|
||||
{
|
||||
if (check_device() == false) return;
|
||||
if (check_device() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
struct iio_buffer *rxbuf;
|
||||
|
||||
@ -1178,16 +1219,14 @@ void ad936x_iio_custom::capture(const std::vector<std::string> &channels)
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::vector<std::string>::const_iterator it =
|
||||
channels.begin();
|
||||
it != channels.end(); ++it)
|
||||
for (const auto &channel : channels)
|
||||
{
|
||||
struct iio_channel *chn =
|
||||
iio_device_find_channel(stream_dev,
|
||||
it->c_str(), false);
|
||||
channel.c_str(), false);
|
||||
if (!chn)
|
||||
{
|
||||
std::cerr << "Channel " << it->c_str() << " not found\n";
|
||||
std::cerr << "Channel " << channel.c_str() << " not found\n";
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -1246,7 +1285,10 @@ void ad936x_iio_custom::capture(const std::vector<std::string> &channels)
|
||||
|
||||
items_in_buffer = static_cast<unsigned long>(ret) / bytes_to_interleaved_iq_samples;
|
||||
|
||||
if (items_in_buffer == 0) return;
|
||||
if (items_in_buffer == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
current_samples->n_channels = n_channels;
|
||||
current_samples->n_interleaved_iq_samples = items_in_buffer;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*!
|
||||
* \file ad936x_iio_custom.h
|
||||
* \brief A direct IIO custom front-end driver for the AD936x AD front-end family with special FPGA custom functionalities.
|
||||
* \brief A direct IIO custom front-end driver for the AD936x AD front-end
|
||||
* family with special FPGA custom functionalities.
|
||||
* \author Javier Arribas, jarribas(at)cttc.es
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
@ -14,41 +15,41 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SRC_LIBS_ad936x_iio_custom_H_
|
||||
#define SRC_LIBS_ad936x_iio_custom_H_
|
||||
#ifndef GNSS_SDR_AD936X_IIO_CUSTOM_H
|
||||
#define GNSS_SDR_AD936X_IIO_CUSTOM_H
|
||||
|
||||
#include "ad936x_iio_samples.h"
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_time.h"
|
||||
#include "pps_samplestamp.h"
|
||||
#include <boost/atomic.hpp>
|
||||
#include <iio.h>
|
||||
#include <ad9361.h> // multichip sync and high level functions
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <iio/iio.h>
|
||||
#else
|
||||
#include <iio.h>
|
||||
#endif
|
||||
|
||||
#include "ad936x_iio_samples.h"
|
||||
#include <ad9361.h> // multichip sync and high level functions
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
* \{ */
|
||||
/** \addtogroup Signal_Source_libs
|
||||
* \{ */
|
||||
|
||||
|
||||
class ad936x_iio_custom
|
||||
{
|
||||
public:
|
||||
ad936x_iio_custom(int debug_level_, int log_level_);
|
||||
virtual ~ad936x_iio_custom();
|
||||
bool initialize_device(std::string pluto_device_uri, std::string board_type);
|
||||
bool initialize_device(const std::string &pluto_device_uri, const std::string &board_type);
|
||||
|
||||
bool init_config_ad9361_rx(long long bandwidth_,
|
||||
long long sample_rate_,
|
||||
long long freq_,
|
||||
std::string rf_port_select_,
|
||||
std::string rf_filter,
|
||||
std::string gain_mode_rx0_,
|
||||
std::string gain_mode_rx1_,
|
||||
const std::string &rf_port_select_,
|
||||
const std::string &rf_filter,
|
||||
const std::string &gain_mode_rx0_,
|
||||
const std::string &gain_mode_rx1_,
|
||||
double rf_gain_rx0_,
|
||||
double rf_gain_rx1_,
|
||||
bool enable_ch0,
|
||||
@ -61,7 +62,7 @@ public:
|
||||
bool calibrate(int ch, double bw_hz);
|
||||
|
||||
double get_rx_gain(int ch_num);
|
||||
bool setRXGain(int ch_num, std::string gain_mode, double gain_dB);
|
||||
bool setRXGain(int ch_num, const std::string &gain_mode, double gain_dB);
|
||||
|
||||
bool set_antenna_port(int ch, int antenna_idx);
|
||||
double get_frequency(int ch);
|
||||
@ -93,9 +94,9 @@ private:
|
||||
unsigned long long frequency,
|
||||
unsigned long samplerate, unsigned long bandwidth,
|
||||
bool quadrature, bool rfdc, bool bbdc,
|
||||
std::string gain1, double gain1_value,
|
||||
std::string gain2, double gain2_value,
|
||||
std::string port_select);
|
||||
const std::string &gain1, double gain1_value,
|
||||
const std::string &gain2, double gain2_value,
|
||||
const std::string &port_select);
|
||||
|
||||
bool config_ad9361_dds(uint64_t freq_rf_tx_hz_,
|
||||
double tx_attenuation_db_,
|
||||
@ -107,7 +108,7 @@ private:
|
||||
void get_PPS_timestamp();
|
||||
void capture(const std::vector<std::string> &channels);
|
||||
|
||||
bool select_rf_filter(std::string rf_filter);
|
||||
bool select_rf_filter(const std::string &rf_filter);
|
||||
|
||||
void monitor_thread_fn();
|
||||
|
||||
@ -120,15 +121,6 @@ private:
|
||||
struct iio_device *stream_dev;
|
||||
struct iio_device *dds_dev;
|
||||
|
||||
// stream
|
||||
|
||||
uint64_t sample_rate_sps;
|
||||
|
||||
|
||||
int debug_level;
|
||||
int log_level;
|
||||
bool PPS_mode;
|
||||
|
||||
std::mutex mtx;
|
||||
std::condition_variable cv;
|
||||
|
||||
@ -142,6 +134,14 @@ private:
|
||||
std::thread capture_samples_thread;
|
||||
std::thread overflow_monitor_thread;
|
||||
std::thread capture_time_thread;
|
||||
|
||||
// stream
|
||||
uint64_t sample_rate_sps;
|
||||
int debug_level;
|
||||
int log_level;
|
||||
bool PPS_mode;
|
||||
};
|
||||
|
||||
#endif /* SRC_LIBS_ad936x_iio_custom_H_ */
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_AD936X_IIO_CUSTOM_H
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*!
|
||||
* \file ad936x_iio_samples.cc
|
||||
* \brief A class that holds a custom sample buffer for Analog Devices AD936x family front-ends.
|
||||
* \author Javier Arribas, jarribas(at)cttc.es
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2022 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "ad936x_iio_samples.h"
|
||||
|
||||
ad936x_iio_samples::ad936x_iio_samples()
|
||||
{
|
||||
n_bytes = 0;
|
||||
n_interleaved_iq_samples = 0;
|
||||
step_bytes = 0;
|
||||
n_channels = 0;
|
||||
}
|
@ -15,26 +15,32 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SRC_LIBS_ad936x_iio_samples_H_
|
||||
#define SRC_LIBS_ad936x_iio_samples_H_
|
||||
#ifndef GNSS_SDR_AD936X_IIO_SAMPLES_H
|
||||
#define GNSS_SDR_AD936X_IIO_SAMPLES_H
|
||||
|
||||
#define IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES 32768 * 4
|
||||
|
||||
#define IIO_INPUTRAMFIFOSIZE 256
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
* \{ */
|
||||
/** \addtogroup Signal_Source_libs
|
||||
* \{ */
|
||||
|
||||
class ad936x_iio_samples
|
||||
{
|
||||
public:
|
||||
ad936x_iio_samples();
|
||||
uint32_t n_bytes;
|
||||
uint32_t n_interleaved_iq_samples;
|
||||
uint16_t n_channels;
|
||||
uint16_t step_bytes;
|
||||
ad936x_iio_samples() = default;
|
||||
uint32_t n_bytes{0};
|
||||
uint32_t n_interleaved_iq_samples{0};
|
||||
uint16_t n_channels{0};
|
||||
uint16_t step_bytes{0};
|
||||
char buffer[IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES * 4 * 4]; // max 16 bits samples per buffer (4 channels, 2-bytes per I + 2-bytes per Q)
|
||||
};
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif
|
||||
|
271
src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc
Normal file
271
src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc
Normal file
@ -0,0 +1,271 @@
|
||||
/*!
|
||||
* \file ion_gsms_chunk_data.cc
|
||||
* \brief Holds logic for reading and decoding samples from a chunk
|
||||
* \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* 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 "ion_gsms_chunk_data.h"
|
||||
#include <cstring>
|
||||
#if USE_GLOG_AND_GFLAGS
|
||||
#include <glog/logging.h>
|
||||
#else
|
||||
#include <absl/log/log.h>
|
||||
#endif
|
||||
|
||||
|
||||
IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std::vector<std::string>& stream_ids, std::size_t output_stream_offset)
|
||||
: chunk_(chunk),
|
||||
sizeword_(chunk_.SizeWord()),
|
||||
countwords_(chunk_.CountWords())
|
||||
{
|
||||
// Instantiate the Allocator functor
|
||||
Allocator allocator(countwords_, buffer_);
|
||||
// Call with_word_type with the Allocator functor
|
||||
with_word_type(sizeword_, allocator);
|
||||
|
||||
const std::size_t total_bitsize = sizeword_ * countwords_ * 8;
|
||||
std::size_t used_bitsize = 0;
|
||||
std::size_t output_streams = 0;
|
||||
for (const auto& lump : chunk.Lumps())
|
||||
{
|
||||
for (const auto& stream : lump.Streams())
|
||||
{
|
||||
used_bitsize += stream.Packedbits();
|
||||
|
||||
bool found = false;
|
||||
for (const auto& stream_id : stream_ids)
|
||||
{
|
||||
if (stream_id == stream.Id())
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()), output_streams + output_stream_offset);
|
||||
++output_streams;
|
||||
std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor();
|
||||
std::size_t sample_rate = stream.RateFactor();
|
||||
if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization())
|
||||
{
|
||||
// Samples have 'Complex' format
|
||||
sample_bitsize /= 2;
|
||||
sample_rate *= 2;
|
||||
}
|
||||
output_stream_item_size_.push_back(bits_to_item_size(sample_bitsize));
|
||||
output_stream_item_rate_.push_back(sample_rate);
|
||||
}
|
||||
else
|
||||
{
|
||||
streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()), -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output_stream_count_ = output_streams;
|
||||
padding_bitsize_ = total_bitsize - used_bitsize;
|
||||
}
|
||||
|
||||
|
||||
IONGSMSChunkData::~IONGSMSChunkData()
|
||||
{
|
||||
Deleter deleter(static_cast<void*>(buffer_));
|
||||
with_word_type(sizeword_, deleter);
|
||||
}
|
||||
|
||||
|
||||
std::size_t IONGSMSChunkData::read_from_buffer(uint8_t* buffer, std::size_t offset)
|
||||
{
|
||||
memset(buffer_, 0, sizeword_ * countwords_);
|
||||
memcpy(buffer_, &buffer[offset], sizeword_ * countwords_);
|
||||
return sizeword_ * countwords_;
|
||||
}
|
||||
|
||||
|
||||
void IONGSMSChunkData::write_to_output(gr_vector_void_star& outputs, std::vector<int>& output_items)
|
||||
{
|
||||
switch (sizeword_)
|
||||
{
|
||||
case 1:
|
||||
unpack_words<int8_t>(outputs, output_items);
|
||||
break;
|
||||
case 2:
|
||||
unpack_words<int16_t>(outputs, output_items);
|
||||
break;
|
||||
case 4:
|
||||
unpack_words<int32_t>(outputs, output_items);
|
||||
break;
|
||||
case 8:
|
||||
unpack_words<int64_t>(outputs, output_items);
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR) << "Unknown word size (" << std::to_string(sizeword_) << "), unpacking nothing.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::size_t IONGSMSChunkData::output_stream_count() const
|
||||
{
|
||||
return output_stream_count_;
|
||||
}
|
||||
|
||||
|
||||
std::size_t IONGSMSChunkData::output_stream_item_size(std::size_t stream_index) const
|
||||
{
|
||||
return output_stream_item_size_[stream_index];
|
||||
}
|
||||
|
||||
|
||||
std::size_t IONGSMSChunkData::output_stream_item_rate(std::size_t stream_index) const
|
||||
{
|
||||
return output_stream_item_rate_[stream_index];
|
||||
}
|
||||
|
||||
|
||||
template <typename WT>
|
||||
void IONGSMSChunkData::unpack_words(gr_vector_void_star& outputs, std::vector<int>& output_items)
|
||||
{
|
||||
WT* data = static_cast<WT*>(buffer_);
|
||||
// TODO - Swap endiannes if needed
|
||||
|
||||
IONGSMSChunkUnpackingCtx<WT> ctx{
|
||||
chunk_.Shift(),
|
||||
data,
|
||||
countwords_,
|
||||
};
|
||||
|
||||
// Head padding
|
||||
if (padding_bitsize_ > 0 && chunk_.Padding() == GnssMetadata::Chunk::Head)
|
||||
{
|
||||
ctx.shift_padding(padding_bitsize_);
|
||||
}
|
||||
|
||||
// Samples
|
||||
for (const auto& [lump, stream, encoding, output_index] : streams_)
|
||||
{
|
||||
if (output_index == -1)
|
||||
{
|
||||
// skip stream
|
||||
ctx.shift_padding(stream.Packedbits());
|
||||
}
|
||||
else
|
||||
{
|
||||
output_items[output_index] += write_stream_samples(ctx, lump, stream, encoding, &outputs[output_index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename WT>
|
||||
std::size_t IONGSMSChunkData::write_stream_samples(
|
||||
IONGSMSChunkUnpackingCtx<WT>& ctx,
|
||||
const GnssMetadata::Lump& lump,
|
||||
const GnssMetadata::IonStream& stream,
|
||||
const GnssMetadata::StreamEncoding stream_encoding,
|
||||
void** out)
|
||||
{
|
||||
std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor();
|
||||
std::size_t sample_count = stream.RateFactor();
|
||||
|
||||
if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization())
|
||||
{
|
||||
// Samples have 'Complex' format
|
||||
sample_bitsize /= 2;
|
||||
sample_count *= 2;
|
||||
}
|
||||
|
||||
if (sample_bitsize <= 8)
|
||||
{
|
||||
write_n_samples<WT, int8_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast<int8_t**>(out));
|
||||
}
|
||||
else if (sample_bitsize <= 16)
|
||||
{
|
||||
write_n_samples<WT, int16_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast<int16_t**>(out));
|
||||
}
|
||||
else if (sample_bitsize <= 32)
|
||||
{
|
||||
write_n_samples<WT, int32_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast<int32_t**>(out));
|
||||
}
|
||||
else if (sample_bitsize <= 64)
|
||||
{
|
||||
write_n_samples<WT, int64_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast<int64_t**>(out));
|
||||
}
|
||||
|
||||
return sample_count;
|
||||
}
|
||||
|
||||
|
||||
template <typename WT, typename OT>
|
||||
void IONGSMSChunkData::write_n_samples(
|
||||
IONGSMSChunkUnpackingCtx<WT>& ctx,
|
||||
GnssMetadata::Lump::LumpShift lump_shift,
|
||||
uint8_t sample_bitsize,
|
||||
std::size_t sample_count,
|
||||
GnssMetadata::StreamEncoding stream_encoding,
|
||||
OT** out)
|
||||
{
|
||||
if (lump_shift == GnssMetadata::Lump::shiftRight)
|
||||
{
|
||||
auto* sample = static_cast<OT*>(*out);
|
||||
sample += sample_count;
|
||||
for (std::size_t i = 0; i < sample_count; ++i)
|
||||
{
|
||||
*sample = 0;
|
||||
ctx.shift_sample(sample_bitsize, sample);
|
||||
decode_sample(sample_bitsize, sample, stream_encoding);
|
||||
--sample;
|
||||
}
|
||||
}
|
||||
else // if (lump_shift == GnssMetadata::Lump::shiftLeft || lump_shift == GnssMetadata::Lump::shiftUndefined)
|
||||
{
|
||||
auto* sample = static_cast<OT*>(*out);
|
||||
for (std::size_t i = 0; i < sample_count; ++i)
|
||||
{
|
||||
*sample = 0;
|
||||
ctx.shift_sample(sample_bitsize, sample);
|
||||
decode_sample(sample_bitsize, sample, stream_encoding);
|
||||
++sample;
|
||||
}
|
||||
}
|
||||
|
||||
(*out) += sample_count;
|
||||
}
|
||||
|
||||
|
||||
// Static utilities
|
||||
template <typename Sample>
|
||||
void IONGSMSChunkData::decode_sample(const uint8_t sample_bitsize, Sample* sample, const GnssMetadata::StreamEncoding encoding)
|
||||
{
|
||||
// using SampleType = std::remove_pointer_t<decltype(sample)>;
|
||||
switch (sample_bitsize)
|
||||
{
|
||||
case 2:
|
||||
*sample = GnssMetadata::two_bit_look_up<Sample>[encoding][*sample];
|
||||
break;
|
||||
case 3:
|
||||
*sample = GnssMetadata::three_bit_look_up<Sample>[encoding][*sample];
|
||||
break;
|
||||
case 4:
|
||||
*sample = GnssMetadata::four_bit_look_up<Sample>[encoding][*sample];
|
||||
break;
|
||||
case 5:
|
||||
*sample = GnssMetadata::five_bit_look_up<Sample>[encoding][*sample];
|
||||
break;
|
||||
default:
|
||||
// TODO - Is this an error that can happen?
|
||||
// for now we'll just do nothing, if the sample is this wide it may need no decoding
|
||||
break;
|
||||
}
|
||||
}
|
188
src/algorithms/signal_source/libs/ion_gsms_chunk_data.h
Normal file
188
src/algorithms/signal_source/libs/ion_gsms_chunk_data.h
Normal file
@ -0,0 +1,188 @@
|
||||
/*!
|
||||
* \file ion_gsms_chunk_data.h
|
||||
* \brief Holds logic for reading and decoding samples from a chunk
|
||||
* \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* 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_ION_GSMS_CHUNK_DATA_H
|
||||
#define GNSS_SDR_ION_GSMS_CHUNK_DATA_H
|
||||
|
||||
#include "ion_gsms_chunk_unpacking_ctx.h"
|
||||
#include "ion_gsms_stream_encodings.h"
|
||||
#include <gnuradio/block.h>
|
||||
#include <GnssMetadata.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
inline std::size_t bits_to_item_size(std::size_t bit_count)
|
||||
{
|
||||
if (bit_count <= 8)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (bit_count <= 16)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
if (bit_count <= 32)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
if (bit_count <= 64)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
// You are asking too much of this humble processor
|
||||
std::cerr << "Item size too large (" << std::to_string(bit_count) << "), returning nonsense.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Define a functor that has a templated operator()
|
||||
struct Allocator
|
||||
{
|
||||
size_t countwords_;
|
||||
void*& buffer_; // Using void* to hold any type of pointer
|
||||
|
||||
Allocator(size_t countwords, void*& buffer)
|
||||
: countwords_(countwords), buffer_(buffer) {}
|
||||
|
||||
template <typename WordType>
|
||||
void operator()() const
|
||||
{
|
||||
buffer_ = new WordType[countwords_];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Define a functor to delete the allocated memory
|
||||
struct Deleter
|
||||
{
|
||||
void* buffer_;
|
||||
|
||||
explicit Deleter(void* buffer)
|
||||
: buffer_(buffer) {}
|
||||
|
||||
template <typename WordType>
|
||||
void operator()() const
|
||||
{
|
||||
delete[] static_cast<WordType*>(buffer_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Callback>
|
||||
void with_word_type(uint8_t word_size, Callback callback)
|
||||
{
|
||||
switch (word_size)
|
||||
{
|
||||
case 1:
|
||||
callback.template operator()<int8_t>();
|
||||
break;
|
||||
case 2:
|
||||
callback.template operator()<int16_t>();
|
||||
break;
|
||||
case 4:
|
||||
callback.template operator()<int32_t>();
|
||||
break;
|
||||
case 8:
|
||||
callback.template operator()<int64_t>();
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Unknown word size (" << std::to_string(word_size) << "), returning nonsense.\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
class IONGSMSChunkData
|
||||
{
|
||||
public:
|
||||
IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std::vector<std::string>& stream_ids, std::size_t output_stream_offset);
|
||||
|
||||
~IONGSMSChunkData();
|
||||
|
||||
IONGSMSChunkData(const IONGSMSChunkData& rhl) = delete;
|
||||
IONGSMSChunkData& operator=(const IONGSMSChunkData& rhl) = delete;
|
||||
|
||||
IONGSMSChunkData(IONGSMSChunkData&& rhl) = delete;
|
||||
IONGSMSChunkData& operator=(IONGSMSChunkData&& rhl) = delete;
|
||||
|
||||
std::size_t read_from_buffer(uint8_t* buffer, std::size_t offset);
|
||||
|
||||
void write_to_output(gr_vector_void_star& outputs, std::vector<int>& output_items);
|
||||
|
||||
std::size_t output_stream_count() const;
|
||||
std::size_t output_stream_item_size(std::size_t stream_index) const;
|
||||
std::size_t output_stream_item_rate(std::size_t stream_index) const;
|
||||
|
||||
private:
|
||||
template <typename WT>
|
||||
void unpack_words(gr_vector_void_star& outputs, std::vector<int>& output_items);
|
||||
|
||||
template <typename WT>
|
||||
std::size_t write_stream_samples(
|
||||
IONGSMSChunkUnpackingCtx<WT>& ctx,
|
||||
const GnssMetadata::Lump& lump,
|
||||
const GnssMetadata::IonStream& stream,
|
||||
GnssMetadata::StreamEncoding stream_encoding,
|
||||
void** out);
|
||||
|
||||
template <typename WT, typename OT>
|
||||
void write_n_samples(
|
||||
IONGSMSChunkUnpackingCtx<WT>& ctx,
|
||||
GnssMetadata::Lump::LumpShift lump_shift,
|
||||
uint8_t sample_bitsize,
|
||||
std::size_t sample_count,
|
||||
GnssMetadata::StreamEncoding stream_encoding,
|
||||
OT** out);
|
||||
|
||||
template <typename Sample>
|
||||
static void decode_sample(uint8_t sample_bitsize, Sample* sample, GnssMetadata::StreamEncoding encoding);
|
||||
|
||||
const GnssMetadata::Chunk& chunk_;
|
||||
uint8_t sizeword_;
|
||||
uint8_t countwords_;
|
||||
uint8_t padding_bitsize_;
|
||||
std::size_t output_stream_count_;
|
||||
std::vector<std::size_t> output_stream_item_size_;
|
||||
std::vector<std::size_t> output_stream_item_rate_;
|
||||
|
||||
struct stream_metadata_t
|
||||
{
|
||||
const GnssMetadata::Lump& lump;
|
||||
const GnssMetadata::IonStream& stream;
|
||||
GnssMetadata::StreamEncoding stream_encoding;
|
||||
int output_index = -1;
|
||||
|
||||
stream_metadata_t(
|
||||
const GnssMetadata::Lump& lump_,
|
||||
const GnssMetadata::IonStream& stream_,
|
||||
GnssMetadata::StreamEncoding stream_encoding_,
|
||||
int output_index_ = -1) : lump(lump_),
|
||||
stream(stream_),
|
||||
stream_encoding(stream_encoding_),
|
||||
output_index(output_index_)
|
||||
{
|
||||
}
|
||||
};
|
||||
std::vector<stream_metadata_t> streams_;
|
||||
|
||||
void* buffer_;
|
||||
};
|
||||
|
||||
#endif // GNSS_SDR_ION_GSMS_CHUNK_DATA_H
|
184
src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h
Normal file
184
src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h
Normal file
@ -0,0 +1,184 @@
|
||||
/*!
|
||||
* \file ion_gsms_chunk_unpacking_ctx.h
|
||||
* \brief Holds state and provides utilities for unpacking samples from a chunk
|
||||
* \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com
|
||||
*
|
||||
* This is a template class, and thus, its member functions must be defined in the header 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_ION_GSMS_CHUNK_UNPACKING_CTX_H
|
||||
#define GNSS_SDR_ION_GSMS_CHUNK_UNPACKING_CTX_H
|
||||
|
||||
#include <gnuradio/block.h>
|
||||
#include <GnssMetadata.h>
|
||||
#include <cstdint>
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
* \{ */
|
||||
/** \addtogroup Signal_Source_libs
|
||||
* \{ */
|
||||
|
||||
template <typename WT>
|
||||
struct IONGSMSChunkUnpackingCtx
|
||||
{
|
||||
static constexpr uint8_t word_bitsize_ = sizeof(WT) * 8;
|
||||
|
||||
const GnssMetadata::Chunk::WordShift word_shift_direction_;
|
||||
WT* iterator_ = nullptr; // Not owned by this class, MUST NOT destroy
|
||||
WT current_word_{};
|
||||
uint8_t bitshift_ = 0;
|
||||
|
||||
IONGSMSChunkUnpackingCtx(
|
||||
const GnssMetadata::Chunk::WordShift word_shift,
|
||||
WT* data_buffer,
|
||||
uint8_t data_buffer_word_count) : word_shift_direction_(word_shift)
|
||||
{
|
||||
if (word_shift_direction_ == GnssMetadata::Chunk::Left)
|
||||
{
|
||||
iterator_ = data_buffer;
|
||||
}
|
||||
else if (word_shift_direction_ == GnssMetadata::Chunk::Right)
|
||||
{
|
||||
iterator_ = &data_buffer[data_buffer_word_count];
|
||||
}
|
||||
if (iterator_)
|
||||
{
|
||||
advance_word(); // Initializes current_word_
|
||||
}
|
||||
}
|
||||
|
||||
void advance_word()
|
||||
{
|
||||
WT word = *iterator_;
|
||||
if (word_shift_direction_ == GnssMetadata::Chunk::Left)
|
||||
{
|
||||
++iterator_;
|
||||
}
|
||||
else if (word_shift_direction_ == GnssMetadata::Chunk::Right)
|
||||
{
|
||||
--iterator_;
|
||||
}
|
||||
|
||||
current_word_ = word;
|
||||
}
|
||||
|
||||
void shift_current_word(uint8_t n)
|
||||
{
|
||||
if ((n % word_bitsize_) == 0)
|
||||
{
|
||||
for (uint8_t i = 0; i < (n / word_bitsize_); ++i)
|
||||
{
|
||||
advance_word();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (word_shift_direction_ == GnssMetadata::Chunk::Left)
|
||||
{
|
||||
current_word_ <<= n;
|
||||
}
|
||||
else if (word_shift_direction_ == GnssMetadata::Chunk::Right)
|
||||
{
|
||||
current_word_ >>= n;
|
||||
}
|
||||
|
||||
bitshift_ += n;
|
||||
if (bitshift_ >= word_bitsize_)
|
||||
{
|
||||
advance_word();
|
||||
bitshift_ -= word_bitsize_;
|
||||
}
|
||||
}
|
||||
|
||||
void shift_padding(uint8_t n_bits)
|
||||
{
|
||||
if (n_bits == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((n_bits + (bitshift_ % word_bitsize_)) >= word_bitsize_)
|
||||
{
|
||||
const uint8_t bits_shifted = word_bitsize_ - (bitshift_ % word_bitsize_);
|
||||
|
||||
shift_current_word(bits_shifted);
|
||||
shift_padding(n_bits - bits_shifted);
|
||||
}
|
||||
else
|
||||
{
|
||||
shift_current_word(n_bits);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename OT>
|
||||
void shift_sample(uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0)
|
||||
{
|
||||
if (sample_bitsize % word_bitsize_ == 0)
|
||||
{
|
||||
const uint8_t words_per_sample = sample_bitsize / word_bitsize_;
|
||||
for (uint8_t i = 0; i < words_per_sample; ++i)
|
||||
{
|
||||
if (word_shift_direction_ == GnssMetadata::Chunk::Left)
|
||||
{
|
||||
*output |= (current_word_ << ((words_per_sample - 1 - i) * word_bitsize_));
|
||||
}
|
||||
else if (word_shift_direction_ == GnssMetadata::Chunk::Right)
|
||||
{
|
||||
*output |= (current_word_ << (i * word_bitsize_));
|
||||
// TODO - reverse bit order of sample? maybe?
|
||||
}
|
||||
advance_word();
|
||||
}
|
||||
}
|
||||
else if ((sample_bitsize + (bitshift_ % word_bitsize_)) > word_bitsize_)
|
||||
{
|
||||
const uint8_t bits_shifted = word_bitsize_ - (bitshift_ % word_bitsize_);
|
||||
|
||||
if (word_shift_direction_ == GnssMetadata::Chunk::Left)
|
||||
{
|
||||
WT mask = ~((1 << (word_bitsize_ - bits_shifted)) - 1);
|
||||
*output |= ((current_word_ & mask) >> output_bit_offset);
|
||||
}
|
||||
else if (word_shift_direction_ == GnssMetadata::Chunk::Right)
|
||||
{
|
||||
WT mask = ((1 << (bits_shifted)) - 1);
|
||||
*output |= (current_word_ & mask) << output_bit_offset;
|
||||
// TODO - reverse bit order of sample? maybe?
|
||||
}
|
||||
|
||||
shift_current_word(bits_shifted);
|
||||
shift_sample(sample_bitsize - bits_shifted, output, bits_shifted);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (word_shift_direction_ == GnssMetadata::Chunk::Left)
|
||||
{
|
||||
WT mask = ~((1 << (word_bitsize_ - sample_bitsize)) - 1);
|
||||
OT sample = (current_word_ & mask) >> (word_bitsize_ - sample_bitsize);
|
||||
*output |= (sample) >> output_bit_offset;
|
||||
}
|
||||
else if (word_shift_direction_ == GnssMetadata::Chunk::Right)
|
||||
{
|
||||
WT mask = ((1 << (sample_bitsize)) - 1);
|
||||
*output |= (current_word_ & mask) << output_bit_offset;
|
||||
// TODO - reverse bit order of sample? maybe?
|
||||
}
|
||||
|
||||
shift_current_word(sample_bitsize);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_ION_GSMS_CHUNK_UNPACKING_CTX_H
|
170
src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h
Normal file
170
src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h
Normal file
@ -0,0 +1,170 @@
|
||||
/*!
|
||||
* \file ion_gsms_stream_encodings.h
|
||||
* \brief Implements look up tables for all encodings in the standard
|
||||
* \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com
|
||||
*
|
||||
* These tables are taken from the stardard's official document.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* 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_ION_GSMS_STREAM_ENCODINGS_H
|
||||
#define GNSS_SDR_ION_GSMS_STREAM_ENCODINGS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
* \{ */
|
||||
/** \addtogroup Signal_Source_libs
|
||||
* \{ */
|
||||
|
||||
namespace GnssMetadata
|
||||
{
|
||||
|
||||
using StreamEncoding = unsigned char;
|
||||
|
||||
namespace StreamEncodings
|
||||
{
|
||||
|
||||
constexpr unsigned char SIGN = 0;
|
||||
constexpr unsigned char OB = 1;
|
||||
constexpr unsigned char SM = 2;
|
||||
constexpr unsigned char MS = 3;
|
||||
constexpr unsigned char TC = 4;
|
||||
constexpr unsigned char OG = 5;
|
||||
constexpr unsigned char OBA = 6;
|
||||
constexpr unsigned char SMA = 7;
|
||||
constexpr unsigned char MSA = 8;
|
||||
constexpr unsigned char TCA = 9;
|
||||
constexpr unsigned char OGA = 10;
|
||||
constexpr unsigned char FP = 11;
|
||||
|
||||
} // namespace StreamEncodings
|
||||
|
||||
inline StreamEncoding encoding_from_string(const std::string& str)
|
||||
{
|
||||
if (str == "SIGN")
|
||||
{
|
||||
return StreamEncodings::SIGN;
|
||||
}
|
||||
if (str == "OB")
|
||||
{
|
||||
return StreamEncodings::OB;
|
||||
}
|
||||
if (str == "SM")
|
||||
{
|
||||
return StreamEncodings::SM;
|
||||
}
|
||||
if (str == "MS")
|
||||
{
|
||||
return StreamEncodings::MS;
|
||||
}
|
||||
if (str == "TC")
|
||||
{
|
||||
return StreamEncodings::TC;
|
||||
}
|
||||
if (str == "OG")
|
||||
{
|
||||
return StreamEncodings::OG;
|
||||
}
|
||||
if (str == "OBA")
|
||||
{
|
||||
return StreamEncodings::OBA;
|
||||
}
|
||||
if (str == "SMA")
|
||||
{
|
||||
return StreamEncodings::SMA;
|
||||
}
|
||||
if (str == "MSA")
|
||||
{
|
||||
return StreamEncodings::MSA;
|
||||
}
|
||||
if (str == "TCA")
|
||||
{
|
||||
return StreamEncodings::TCA;
|
||||
}
|
||||
if (str == "OGA")
|
||||
{
|
||||
return StreamEncodings::OGA;
|
||||
}
|
||||
if (str == "FP")
|
||||
{
|
||||
return StreamEncodings::FP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T two_bit_look_up[11][4]{
|
||||
{}, // [0]
|
||||
{-2, -1, 0, 1}, // [1 /*OB*/]
|
||||
{0, 1, 0, -1}, // [2 /*SM*/]
|
||||
{0, 0, 1, -1}, // [3 /*MS*/]
|
||||
{0, 1, -2, -1}, // [4 /*TC*/]
|
||||
{-2, -1, 1, 0}, // [5 /*OG*/]
|
||||
{-3, -1, 1, 3}, // [6 /*OBA*/]
|
||||
{1, 3, -1, -3}, // [7 /*SMA*/]
|
||||
{1, -1, 3, -3}, // [8 /*MSA*/]
|
||||
{1, 3, -3, -1}, // [9 /*TCA*/]
|
||||
{-3, -1, 3, 1}, // [10 /*OGA*/]
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline T three_bit_look_up[11][8]{
|
||||
{}, // [0]
|
||||
{-4, -3, -2, -1, 0, 1, 2, 3}, // [1 /*OB*/]
|
||||
{0, 1, 2, 3, 0, -1, -2, -3}, // [2 /*SM*/]
|
||||
{0, 0, 1, -1, 0, 0, 1, -1}, // [3 /*MS*/]
|
||||
{0, 1, 2, 3, -4, -3, -2, -1}, // [4 /*TC*/]
|
||||
{-4, -3, -1, -2, 3, 2, 0, 1}, // [5 /*OG*/]
|
||||
{-7, -5, -3, -1, 1, 3, 5, 7}, // [6 /*OBA*/]
|
||||
{1, 3, 5, 7, -1, -3, -5, -7}, // [7 /*SMA*/]
|
||||
{1, -1, 3, -3, 5, -5, 7, -7}, // [8 /*MSA*/]
|
||||
{1, 3, 5, 7, -7, -5, -3, -1}, // [9 /*TCA*/]
|
||||
{-7, -5, -1, -3, 7, 5, 1, 3}, // [10 /*OGA*/]
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline T four_bit_look_up[11][16]{
|
||||
{}, // [0]
|
||||
{-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, // [1 /*OB*/]
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7}, // [2 /*SM*/]
|
||||
{0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, // [3 /*MS*/]
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}, // [4 /*TC*/]
|
||||
{-8, -7, -5, -6, -1, -2, -4, -3, 7, 6, 4, 5, 0, 1, 3, 2}, // [5 /*OG*/]
|
||||
{-15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15}, // [6 /*OBA*/]
|
||||
{1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15}, // [7 /*SMA*/]
|
||||
{1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15}, // [8 /*MSA*/]
|
||||
{1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1}, // [9 /*TCA*/]
|
||||
{-15, -13, -9, -11, -1, -3, -7, -5, 15, 13, 9, 11, 1, 3, 7, 5}, // [10 /*OGA*/]
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline T five_bit_look_up[11][32]{
|
||||
{}, // [0]
|
||||
{-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, // [1 /*OB*/]
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}, // [2 /*SM*/]
|
||||
{0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, // [3 /*MS*/]
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1}, // [4 /*TC*/]
|
||||
{-16, -15, -13, -14, -9, -10, -12, -11, -1, -2, -4, -3, -8, -7, -5, -6, 15, 14, 12, 13, 8, 9, 11, 10, 0, 1, 3, 2, 7, 6, 4, 5}, // [5 /*OG*/]
|
||||
{-31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, // [6 /*OBA*/]
|
||||
{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -1, -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -29, -31}, // [7 /*SMA*/]
|
||||
{1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15, 17, -17, 19, -19, 21, -21, 23, -23, 25, -25, 27, -27, 29, -29, 31, -31}, // [8 /*MSA*/]
|
||||
{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1}, // [9 /*TCA*/]
|
||||
{-31, -29, -25, -27, -17, -19, -23, -21, -1, -3, -7, -5, -15, -13, -9, -11, 31, 29, 25, 27, 17, 19, 23, 21, 1, 3, 7, 5, 15, 13, 9, 11}, // [10 /*OGA*/]
|
||||
};
|
||||
|
||||
} // namespace GnssMetadata
|
||||
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_ION_GSMS_STREAM_ENCODINGS_H
|
@ -20,19 +20,6 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
pps_tcp_rx::pps_tcp_rx()
|
||||
{
|
||||
// TODO Auto-generated constructor stub
|
||||
is_connected = false;
|
||||
clientSd = -1;
|
||||
}
|
||||
|
||||
|
||||
pps_tcp_rx::~pps_tcp_rx()
|
||||
{
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
|
||||
void pps_tcp_rx::set_pps_samplestamp_queue(std::shared_ptr<Concurrent_Queue<PpsSamplestamp>> queue)
|
||||
{
|
||||
@ -40,7 +27,7 @@ void pps_tcp_rx::set_pps_samplestamp_queue(std::shared_ptr<Concurrent_Queue<PpsS
|
||||
}
|
||||
|
||||
|
||||
bool pps_tcp_rx::send_cmd(std::string cmd)
|
||||
bool pps_tcp_rx::send_cmd(std::string cmd) const
|
||||
{
|
||||
if (is_connected == true)
|
||||
{
|
||||
@ -64,7 +51,7 @@ bool pps_tcp_rx::send_cmd(std::string cmd)
|
||||
}
|
||||
|
||||
|
||||
void pps_tcp_rx::receive_pps(std::string ip_address, int port)
|
||||
void pps_tcp_rx::receive_pps(const std::string &ip_address, int port)
|
||||
{
|
||||
// create a message buffer
|
||||
char buf[1500];
|
||||
@ -117,7 +104,7 @@ void pps_tcp_rx::receive_pps(std::string ip_address, int port)
|
||||
{
|
||||
try
|
||||
{
|
||||
new_pps.samplestamp = std::strtoul(data.at(0).substr(found + 3).c_str(), NULL, 0);
|
||||
new_pps.samplestamp = std::strtoul(data.at(0).substr(found + 3).c_str(), nullptr, 0);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
@ -133,7 +120,7 @@ void pps_tcp_rx::receive_pps(std::string ip_address, int port)
|
||||
{
|
||||
try
|
||||
{
|
||||
new_pps.overflow_reg = std::stoi(data.at(1).substr(found + 2).c_str(), NULL, 0);
|
||||
new_pps.overflow_reg = std::stoi(data.at(1).substr(found + 2).c_str(), nullptr, 0);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
@ -155,7 +142,9 @@ void pps_tcp_rx::receive_pps(std::string ip_address, int port)
|
||||
}
|
||||
}
|
||||
else
|
||||
new_pps_line += c;
|
||||
{
|
||||
new_pps_line += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -28,15 +28,15 @@ class pps_tcp_rx
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<Concurrent_Queue<PpsSamplestamp>> Pps_queue;
|
||||
int clientSd;
|
||||
int clientSd{-1};
|
||||
|
||||
public:
|
||||
volatile bool is_connected;
|
||||
pps_tcp_rx();
|
||||
virtual ~pps_tcp_rx();
|
||||
volatile bool is_connected{false};
|
||||
pps_tcp_rx() = default;
|
||||
virtual ~pps_tcp_rx() = default;
|
||||
|
||||
void receive_pps(std::string ip_address, int port);
|
||||
bool send_cmd(std::string cmd);
|
||||
void receive_pps(const std::string& ip_address, int port);
|
||||
bool send_cmd(std::string cmd) const;
|
||||
|
||||
void set_pps_samplestamp_queue(std::shared_ptr<Concurrent_Queue<PpsSamplestamp>> queue);
|
||||
};
|
||||
|
@ -70,6 +70,10 @@ if(ENABLE_FPGA)
|
||||
target_compile_definitions(core_receiver PUBLIC -DENABLE_FPGA=1)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ION)
|
||||
target_compile_definitions(core_receiver PRIVATE -DENABLE_ION_SOURCE=1)
|
||||
endif()
|
||||
|
||||
if(GNURADIO_USES_STD_POINTERS)
|
||||
target_compile_definitions(core_receiver PUBLIC -DGNURADIO_USES_STD_POINTERS=1)
|
||||
endif()
|
||||
@ -90,6 +94,10 @@ if(ENABLE_PLUTOSDR)
|
||||
target_compile_definitions(core_receiver PRIVATE -DPLUTOSDR_DRIVER=1)
|
||||
endif()
|
||||
|
||||
if(ENABLE_AD936X_SDR)
|
||||
target_compile_definitions(core_receiver PRIVATE -DAD936X_SDR_DRIVER=1)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FMCOMMS2)
|
||||
target_compile_definitions(core_receiver PRIVATE -DFMCOMMS2_DRIVER=1)
|
||||
endif()
|
||||
|
@ -163,6 +163,10 @@
|
||||
#include "plutosdr_signal_source.h"
|
||||
#endif
|
||||
|
||||
#if AD936X_SDR_DRIVER
|
||||
#include "ad936x_custom_signal_source.h"
|
||||
#endif
|
||||
|
||||
#if FMCOMMS2_DRIVER
|
||||
#include "fmcomms2_signal_source.h"
|
||||
#endif
|
||||
@ -196,6 +200,11 @@
|
||||
#include "gps_l1_ca_dll_pll_tracking_gpu.h"
|
||||
#endif
|
||||
|
||||
#if ENABLE_ION_SOURCE
|
||||
#undef Owner
|
||||
#include "ion_gsms_signal_source.h"
|
||||
#endif
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
namespace
|
||||
@ -759,7 +768,14 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
block = std::move(block_);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_ION_SOURCE
|
||||
else if (implementation == "ION_GSMS_Signal_Source")
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<IONGSMSSignalSource>(configuration, role, in_streams,
|
||||
out_streams, queue);
|
||||
block = std::move(block_);
|
||||
}
|
||||
#endif
|
||||
#if RAW_ARRAY_DRIVER
|
||||
else if (implementation == "Raw_Array_Signal_Source")
|
||||
{
|
||||
@ -795,6 +811,8 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
out_streams, queue);
|
||||
block = std::move(block_);
|
||||
}
|
||||
#endif
|
||||
#if PLUTOSDR_DRIVER || AD936X_SDR_DRIVER
|
||||
else if (implementation == "Ad936x_Custom_Signal_Source")
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<Ad936xCustomSignalSource>(configuration, role, in_streams,
|
||||
|
Loading…
Reference in New Issue
Block a user