From 65713d4c820fb1b275a6c233fa1d37f42a75dcda Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Tue, 27 Mar 2018 19:35:53 +0200 Subject: [PATCH] Adding support for dual channel in FMCOMMS2 and optional Local Oscillator generation using FMCOMMS2 TX channel --- cmake/Modules/Findlibiio.cmake | 32 + ...gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf | 114 +++ .../adapters/fmcomms2_signal_source.cc | 91 ++- .../adapters/fmcomms2_signal_source.h | 9 + .../signal_source/libs/CMakeLists.txt | 46 +- .../signal_source/libs/ad9361_manager.cc | 704 ++++++++++++++++++ .../signal_source/libs/ad9361_manager.h | 127 ++++ 7 files changed, 1112 insertions(+), 11 deletions(-) create mode 100644 cmake/Modules/Findlibiio.cmake create mode 100644 conf/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf create mode 100644 src/algorithms/signal_source/libs/ad9361_manager.cc create mode 100644 src/algorithms/signal_source/libs/ad9361_manager.h diff --git a/cmake/Modules/Findlibiio.cmake b/cmake/Modules/Findlibiio.cmake new file mode 100644 index 000000000..a708d7062 --- /dev/null +++ b/cmake/Modules/Findlibiio.cmake @@ -0,0 +1,32 @@ +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(PC_LIBIIO libiio) + +FIND_PATH( + LIBIIO_INCLUDE_DIRS + NAMES gnuradio/iio/api.h + HINTS $ENV{LIBIIO_DIR}/include + ${PC_LIBIIO_INCLUDEDIR} + PATHS ${CMAKE_INSTALL_PREFIX}/include + /usr/local/include + /usr/include +) + +FIND_LIBRARY( + LIBIIO_LIBRARIES + NAMES libiio.so + HINTS $ENV{LIBIIO_DIR}/lib + ${PC_LIBIIO_LIBDIR} + PATHS ${CMAKE_INSTALL_PREFIX}/lib + ${CMAKE_INSTALL_PREFIX}/lib64 + /usr/local/lib + /usr/local/lib64 + /usr/lib + /usr/lib64 + /usr/lib/x86_64-linux-gnu +) + +message("find libiio:") +message(${LIBIIO_LIBRARIES}) +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBIIO DEFAULT_MSG LIBIIO_LIBRARIES LIBIIO_INCLUDE_DIRS) +MARK_AS_ADVANCED(LIBIIO_LIBRARIES LIBIIO_INCLUDE_DIRS) diff --git a/conf/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf b/conf/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf new file mode 100644 index 000000000..80814ad1d --- /dev/null +++ b/conf/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf @@ -0,0 +1,114 @@ +; You can define your own receiver and invoke it by doing +; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf +; + +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [Sps]. +;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE +; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ +GNSS-SDR.internal_fs_sps=7000000 + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource.implementation=Fmcomms2_Signal_Source +SignalSource.item_type=gr_complex +SignalSource.device_address=192.168.0.4 +SignalSource.sampling_frequency=7000000 +SignalSource.freq=1575420000 +SignalSource.bandwidth=4000000 +SignalSource.RF_channels=2 +SignalSource.rx1_enable=true +SignalSource.rx2_enable=true +SignalSource.gain_mode_rx1=slow_attack +SignalSource.gain_mode_rx2=slow_attack +SignalSource.rf_port_select=A_BALANCED +SignalSource.gain_rx1=64 +SignalSource.gain_rx2=64 +SignalSource.samples=0 +SignalSource.repeat=false +SignalSource.dump=false +SignalSource.dump_filename=../data/signal_source.dat +SignalSource.enable_throttle_control=false +SignalSource.enable_dds_lo=false +SignalSource.freq_rf_tx_hz=1260000000 +SignalSource.freq_dds_tx_hz=1000 +SignalSource.scale_dds_dbfs=0.0 +SignalSource.phase_dds_deg=0.0 +SignalSource.tx_attenuation_db=0.0 + + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner0.implementation=Pass_Through +SignalConditioner1.implementation=Pass_Through + +;######### CHANNELS GLOBAL CONFIG ############ +Channels_1C.count=8 +Channels.in_acquisition=1 + +;# CHANNEL CONNECTION +Channel0.RF_channel_ID=0 +Channel0.signal=1C +Channel1.RF_channel_ID=0 +Channel1.signal=1C +Channel2.RF_channel_ID=0 +Channel2.signal=1C +Channel3.RF_channel_ID=0 +Channel3.signal=1C +Channel4.RF_channel_ID=1 +Channel4.signal=1C +Channel5.RF_channel_ID=1 +Channel5.signal=1C +Channel6.RF_channel_ID=1 +Channel6.signal=1C +Channel7.RF_channel_ID=1 +Channel7.signal=1C + +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +Acquisition_1C.item_type=gr_complex +Acquisition_1C.threshold=20 +Acquisition_1C.use_CFAR_algorithm=false +Acquisition_1C.blocking=true +Acquisition_1C.doppler_max=10000 +Acquisition_1C.doppler_step=250 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat + + +;######### TRACKING GLOBAL CONFIG ############ +Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking +Tracking_1C.item_type=gr_complex +Tracking_1C.dump=false +Tracking_1C.dump_filename=./tracking_ch_ +Tracking_1C.pll_bw_hz=35.0; +Tracking_1C.dll_bw_hz=2.0; +Tracking_1C.early_late_space_chips=0.5; + + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder +TelemetryDecoder_1C.dump=false + + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables +Observables.dump=false +Observables.dump_filename=./observables.dat + + +;######### PVT CONFIG ############ +PVT.implementation=RTKLIB_PVT +PVT.positioning_mode=Single ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic +PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX +PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad +PVT.output_rate_ms=100 +PVT.display_rate_ms=500 +PVT.dump_filename=./PVT +PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; +PVT.flag_nmea_tty_port=false; +PVT.nmea_dump_devname=/dev/pts/4 +PVT.flag_rtcm_server=false +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.dump=false diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index 389e9fd36..0b590f722 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -32,7 +32,9 @@ #include "fmcomms2_signal_source.h" #include "configuration_interface.h" #include "gnss_sdr_valve.h" +#include "ad9361_manager.h" #include "GPS_L1_CA.h" +#include "GPS_L2C.h" #include #include @@ -55,6 +57,7 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration quadrature_ = configuration->property(role + ".quadrature", true); rf_dc_ = configuration->property(role + ".rf_dc", true); bb_dc_ = configuration->property(role + ".bb_dc", true); + RF_channels_ = configuration->property(role + ".RF_channels", 1); gain_mode_rx1_ = configuration->property(role + ".gain_mode_rx1", std::string("manual")); gain_mode_rx2_ = configuration->property(role + ".gain_mode_rx2", std::string("manual")); rf_gain_rx1_ = configuration->property(role + ".gain_rx1", 64.0); @@ -67,6 +70,15 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); + //AD9361 Local Oscillator generation for dual band operation + enable_dds_lo_=configuration->property(role + ".enable_dds_lo", false); + freq_rf_tx_hz_=configuration->property(role + ".freq_rf_tx_hz", GPS_L1_FREQ_HZ-GPS_L2_FREQ_HZ-1000); + freq_dds_tx_hz_=configuration->property(role + ".freq_dds_tx_hz", 1000); + scale_dds_dbfs_=configuration->property(role + ".scale_dds_dbfs", 0.0); + phase_dds_deg_=configuration->property(role + ".phase_dds_deg", 0.0); + tx_attenuation_db_=configuration->property(role + ".tx_attenuation_db", 0.0); + + item_size_ = sizeof(gr_complex); std::cout << "device address: " << uri_ << std::endl; @@ -75,15 +87,72 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration if (item_type_.compare("gr_complex") == 0) { - fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make( - uri_.c_str(), freq_, sample_rate_, - bandwidth_, - rx1_en_, rx2_en_, - buffer_size_, quadrature_, rf_dc_, - bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_, - gain_mode_rx2_.c_str(), rf_gain_rx2_, - rf_port_select_.c_str(), filter_file_.c_str(), - filter_auto_); + if (RF_channels_==1) + { + if (rx1_en_ and rx2_en_) + { + LOG(FATAL) << "Configuration error: both rx1 and rx2 are enabled but RF_channels=1 !"; + } + else + { + fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make( + uri_.c_str(), freq_, sample_rate_, + bandwidth_, + rx1_en_, rx2_en_, + buffer_size_, quadrature_, rf_dc_, + bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_, + gain_mode_rx2_.c_str(), rf_gain_rx2_, + rf_port_select_.c_str(), filter_file_.c_str(), + filter_auto_); + + //configure LO + if (enable_dds_lo_==true) + { + std::cout<<"Enabling Local Oscillator generator in FMCOMMS2\n"; + config_ad9361_lo_remote(uri_, + bandwidth_, + sample_rate_, + freq_rf_tx_hz_, + tx_attenuation_db_, + freq_dds_tx_hz_, + scale_dds_dbfs_); + } + } + } + else if(RF_channels_==2) + { + if (!(rx1_en_ and rx2_en_)) + { + LOG(FATAL) << "Configuration error: RF_channels=2 but are not enabled both receivers in FMCOMMS2 !"; + } + else + { + fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make( + uri_.c_str(), freq_, sample_rate_, + bandwidth_, + rx1_en_, rx2_en_, + buffer_size_, quadrature_, rf_dc_, + bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_, + gain_mode_rx2_.c_str(), rf_gain_rx2_, + rf_port_select_.c_str(), filter_file_.c_str(), + filter_auto_); + //configure LO + if (enable_dds_lo_==true) + { + std::cout<<"Enabling Local Oscillator generator in FMCOMMS2\n"; + config_ad9361_lo_remote(uri_, + bandwidth_, + sample_rate_, + freq_rf_tx_hz_, + tx_attenuation_db_, + freq_dds_tx_hz_, + scale_dds_dbfs_); + } + } + }else{ + LOG(FATAL) << "Configuration error: Unsupported number of RF_channels !"; + } + } else { @@ -108,6 +177,10 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration Fmcomms2SignalSource::~Fmcomms2SignalSource() { + if (enable_dds_lo_==true) + { + ad9361_disable_lo_remote(uri_); + } } diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h index 1c24e4b4c..014299981 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h @@ -88,6 +88,7 @@ private: bool quadrature_; bool rf_dc_; bool bb_dc_; + int RF_channels_; std::string gain_mode_rx1_; std::string gain_mode_rx2_; double rf_gain_rx1_; @@ -96,6 +97,14 @@ private: std::string filter_file_; bool filter_auto_; + //DDS configuration for LO generation for external mixer + bool enable_dds_lo_; + unsigned long freq_rf_tx_hz_; + unsigned long freq_dds_tx_hz_; + double scale_dds_dbfs_; + double phase_dds_deg_; + double tx_attenuation_db_; + unsigned int in_stream_; unsigned int out_stream_; diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index 1ecb1edfd..53ad528e9 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -16,16 +16,58 @@ # along with GNSS-SDR. If not, see . # +if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) + find_package(iio REQUIRED) + if(NOT IIO_FOUND) + message(STATUS "gnuradio-iio not found, its installation is required.") + message(STATUS "Please build and install the following projects:") + message(STATUS " * libiio from https://github.com/analogdevicesinc/libiio") + message(STATUS " * libad9361-iio from https://github.com/analogdevicesinc/libad9361-iio") + message(STATUS " * gnuradio-iio from https://github.com/analogdevicesinc/gr-iio") + message(FATAL_ERROR "gnuradio-iio required for building gnss-sdr with this option enabled") + endif(NOT IIO_FOUND) + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${IIO_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) + + find_package(libiio REQUIRED) + if(NOT LIBIIO_FOUND) + message(STATUS "gnuradio-iio not found, its installation is required.") + message(STATUS "Please build and install the following projects:") + message(STATUS " * libiio from https://github.com/analogdevicesinc/libiio") + message(STATUS " * libad9361-iio from https://github.com/analogdevicesinc/libad9361-iio") + message(STATUS " * gnuradio-iio from https://github.com/analogdevicesinc/gr-iio") + message(FATAL_ERROR "gnuradio-iio required for building gnss-sdr with this option enabled") + endif(NOT LIBIIO_FOUND) + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${LIBIIO_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${LIBIIO_INCLUDE_DIRS}) + +endif(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) + +if(ENABLE_FMCOMMS2) + ############################################### + # FMCOMMS2 based SDR Hardware + ############################################### + if(IIO_FOUND) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ad9361_manager.cc) + endif(IIO_FOUND) +endif(ENABLE_FMCOMMS2) + set (SIGNAL_SOURCE_LIB_SOURCES rtl_tcp_commands.cc - rtl_tcp_dongle_info.cc) + rtl_tcp_dongle_info.cc + ${OPT_SIGNAL_SOURCE_LIB_SOURCES}) include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${Boost_INCLUDE_DIRS} + ${OPT_DRIVER_INCLUDE_DIRS} ) + file(GLOB SIGNAL_SOURCE_LIB_HEADERS "*.h") list(SORT SIGNAL_SOURCE_LIB_HEADERS) add_library(signal_source_lib ${SIGNAL_SOURCE_LIB_SOURCES} ${SIGNAL_SOURCE_LIB_HEADERS}) -source_group(Headers FILES ${SIGNAL_SOURCE_LIB_HEADERS}) \ No newline at end of file +source_group(Headers FILES ${SIGNAL_SOURCE_LIB_HEADERS}) + +target_link_libraries(signal_source_lib ${OPT_LIBRARIES}) + diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc new file mode 100644 index 000000000..66a95ee14 --- /dev/null +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -0,0 +1,704 @@ +/*! + * \file ad9361_manager.cc + * \brief An Analog Devices AD9361 front-end configuration library wrapper for configure some functions via iiod link. + * \author Javier Arribas, jarribas(at)cttc.es + * + * This file contains information taken from librtlsdr: + * http://git.osmocom.org/rtl-sdr/ + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ +#include "ad9361_manager.h" +#include +#include +#include +#include + +/* check return value of attr_write function */ +void errchk(int v, const char* what) { + if (v < 0) + { + LOG(WARNING)<<"Error "<rfport); + wr_ch_lli(chn, "rf_bandwidth", cfg->bw_hz); + wr_ch_lli(chn, "sampling_frequency", cfg->fs_hz); + + // Configure LO channel + //LOG(INFO)<<"* Acquiring AD9361 "<lo_hz); + return true; +} + + +bool config_ad9361_rx_local(unsigned long bandwidth_, + unsigned long sample_rate_, + unsigned long freq_, + std::string rf_port_select_, + std::string gain_mode_rx1_, + std::string gain_mode_rx2_, + double rf_gain_rx1_, + double rf_gain_rx2_) + +{ + // RX stream config + // Stream configurations + struct stream_cfg rxcfg; + rxcfg.bw_hz = bandwidth_; // 2 MHz rf bandwidth + rxcfg.fs_hz = sample_rate_; // 2.5 MS/s rx sample rate + rxcfg.lo_hz = freq_; // 2.5 GHz rf frequency + rxcfg.rfport = rf_port_select_.c_str(); // port A (select for rf freq.) + + std::cout<<"AD9361 Acquiring IIO LOCAL context\n"; + struct iio_context *ctx; + // Streaming devices + struct iio_device *rx; + struct iio_channel *rx0_i; + struct iio_channel *rx0_q; + + ctx = iio_create_default_context(); + if (!ctx) + { + std::cout<<"No context\n"; + throw std::runtime_error("AD9361 IIO No context"); + } + + if (iio_context_get_devices_count(ctx) <= 0) + { + std::cout<<"No devices\n"; + throw std::runtime_error("AD9361 IIO No devices"); + } + + std::cout<<"* Acquiring AD9361 streaming devices\n"; + + if(!get_ad9361_stream_dev(ctx, RX, &rx)) + { + std::cout<<"No rx dev found\n"; + throw std::runtime_error("AD9361 IIO No rx dev found"); + }; + + std::cout<<"* Configuring AD9361 for streaming\n"; + if (!cfg_ad9361_streaming_ch(ctx, &rxcfg, RX, 0)) + { + std::cout<<"RX port 0 not found\n"; + throw std::runtime_error("AD9361 IIO RX port 0 not found"); + } + + std::cout<<"* Initializing AD9361 IIO streaming channels\n"; + if (!get_ad9361_stream_ch(ctx, RX, rx, 0, &rx0_i)) + { + std::cout<<"RX chan i not found\n"; + throw std::runtime_error("RX chan i not found"); + } + + if (!get_ad9361_stream_ch(ctx, RX, rx, 1, &rx0_q)) + { + std::cout<<"RX chan q not found\n"; + throw std::runtime_error("RX chan q not found"); + } + + std::cout<<"* Enabling IIO streaming channels\n"; + iio_channel_enable(rx0_i); + iio_channel_enable(rx0_q); + + struct iio_device *ad9361_phy; + ad9361_phy= iio_context_find_device(ctx, "ad9361-phy"); + int ret; + ret=iio_device_attr_write(ad9361_phy,"trx_rate_governor","nominal"); + if (ret < 0) { + std::cout<<"Failed to set trx_rate_governor: "<. + * + * ------------------------------------------------------------------------- + */ + +#ifndef __AD9361_MANAGER__ +#define __AD9361_MANAGER__ + +#include + +#ifdef __APPLE__ +#include +#else +#include +#endif + +/* RX is input, TX is output */ +enum iodev { RX, TX }; + +/* common RX and TX streaming params */ +struct stream_cfg { + long long bw_hz; // Analog banwidth in Hz + long long fs_hz; // Baseband sample rate in Hz + long long lo_hz; // Local oscillator frequency in Hz + const char* rfport; // Port name +}; + + +/* check return value of attr_write function */ +void errchk(int v, const char* what); + +/* write attribute: long long int */ +void wr_ch_lli(struct iio_channel *chn, const char* what, long long val); + +/* write attribute: string */ +void wr_ch_str(struct iio_channel *chn, const char* what, const char* str); + +/* helper function generating channel names */ +char* get_ch_name(const char* type, int id, char* tmpstr); + +/* returns ad9361 phy device */ +struct iio_device* get_ad9361_phy(struct iio_context *ctx); + +/* finds AD9361 streaming IIO devices */ +bool get_ad9361_stream_dev(struct iio_context *ctx, enum iodev d, struct iio_device **dev); + +/* finds AD9361 streaming IIO channels */ +bool get_ad9361_stream_ch(struct iio_context *ctx, enum iodev d, struct iio_device *dev, int chid, struct iio_channel **chn); + +/* finds AD9361 phy IIO configuration channel with id chid */ +bool get_phy_chan(struct iio_context *ctx, enum iodev d, int chid, struct iio_channel **chn); + +/* finds AD9361 local oscillator IIO configuration channels */ +bool get_lo_chan(struct iio_context *ctx, enum iodev d, struct iio_channel **chn); + +/* applies streaming configuration through IIO */ +bool cfg_ad9361_streaming_ch(struct iio_context *ctx, struct stream_cfg *cfg, enum iodev type, int chid); + + +bool config_ad9361_rx_local(unsigned long bandwidth_, + unsigned long sample_rate_, + unsigned long freq_, + std::string rf_port_select_, + std::string gain_mode_rx1_, + std::string gain_mode_rx2_, + double rf_gain_rx1_, + double rf_gain_rx2_); + +bool config_ad9361_rx_remote(std::string remote_host, + unsigned long bandwidth_, + unsigned long sample_rate_, + unsigned long freq_, + std::string rf_port_select_, + std::string gain_mode_rx1_, + std::string gain_mode_rx2_, + double rf_gain_rx1_, + double rf_gain_rx2_); + +bool config_ad9361_lo_local(unsigned long bandwidth_, + unsigned long sample_rate_, + unsigned long freq_rf_tx_hz_, + double tx_attenuation_db_, + long long freq_dds_tx_hz_, + double scale_dds_dbfs_); + +bool config_ad9361_lo_remote(std::string remote_host, + unsigned long bandwidth_, + unsigned long sample_rate_, + unsigned long freq_rf_tx_hz_, + double tx_attenuation_db_, + long long freq_dds_tx_hz_, + double scale_dds_dbfs_); + + +bool ad9361_disable_lo_remote(std::string remote_host); + +bool ad9361_disable_lo_local(); + + +#endif