From 48a62594eb2a17b8f8cb3bf6c695dff9a1b49369 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 7 Oct 2019 22:45:09 +0200 Subject: [PATCH 01/19] Add work on RF configuration parameters for AD9361 --- .../adapters/ad9361_fpga_signal_source.cc | 120 ++++++++++++----- .../adapters/ad9361_fpga_signal_source.h | 3 +- .../adapters/fmcomms2_signal_source.cc | 125 +++++++++++++++--- .../adapters/fmcomms2_signal_source.h | 18 +-- .../adapters/plutosdr_signal_source.cc | 44 +++++- .../adapters/plutosdr_signal_source.h | 13 +- .../signal_source/libs/ad9361_manager.cc | 20 ++- 7 files changed, 266 insertions(+), 77 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc index c2cc90137..4a5febc21 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc @@ -37,6 +37,7 @@ #include "configuration_interface.h" #include #include +#include // for abs #include #include // for open, O_WRONLY #include // for std::ifstream @@ -277,6 +278,11 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura const std::string &role, unsigned int in_stream, unsigned int out_stream, std::shared_ptr> queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream), queue_(std::move(queue)) { + std::string default_gain_mode("slow attack"); + double default_tx_attenuation_db = -10.0; + double default_manual_gain_rx1 = 64.0; + double default_manual_gain_rx2 = 64.0; + std::string default_rf_port_select("A_BALANCED"); freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ); sample_rate_ = configuration->property(role + ".sampling_frequency", 12500000); bandwidth_ = configuration->property(role + ".bandwidth", 12500000); @@ -286,25 +292,33 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura quadrature_ = configuration->property(role + ".quadrature", true); rf_dc_ = configuration->property(role + ".rf_dc", true); bb_dc_ = configuration->property(role + ".bb_dc", true); - 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); - rf_gain_rx2_ = configuration->property(role + ".gain_rx2", 64.0); - rf_port_select_ = configuration->property(role + ".rf_port_select", std::string("A_BALANCED")); + 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_gain_rx1_ = configuration->property(role + ".gain_rx1", default_manual_gain_rx1); + rf_gain_rx2_ = configuration->property(role + ".gain_rx2", default_manual_gain_rx2); + rf_port_select_ = configuration->property(role + ".rf_port_select", default_rf_port_select); filter_file_ = configuration->property(role + ".filter_file", std::string("")); - filter_auto_ = configuration->property(role + ".filter_auto", true); + filter_auto_ = configuration->property(role + ".filter_auto", false); samples_ = configuration->property(role + ".samples", 0); 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", -3.0); phase_dds_deg_ = configuration->property(role + ".phase_dds_deg", 0.0); - tx_attenuation_db_ = configuration->property(role + ".tx_attenuation_db", 0.0); + tx_attenuation_db_ = configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db); + tx_bandwidth_ = configuration->property(role + ".tx_bandwidth", 500000); // turn switch to A/D position std::string default_device_name = "/dev/uio1"; std::string device_name = configuration->property(role + ".devicename", default_device_name); switch_position = configuration->property(role + ".switch_position", 0); + if (switch_position != 0 && switch_position != 2) + { + std::cout << "SignalSource.switch_position configuration parameter must be either 0: read from file(s) via DMA, or 2: read from AD9361" << std::endl; + std::cout << "SignalSource.switch_position configuration parameter set to its default value switch_position=0 - read from file(s)" << std::endl; + switch_position = 0; + } + switch_fpga = std::make_shared(device_name); switch_fpga->set_switch_position(switch_position); @@ -348,8 +362,9 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura std::cout << "Configuration parameter rf_port_select should take one of these values:" << std::endl; std::cout << " A_BALANCED, B_BALANCED, A_N, B_N, B_P, C_N, C_P, TX_MONITOR1, TX_MONITOR2, TX_MONITOR1_2" << std::endl; std::cout << "Error: provided value rf_port_select=" << rf_port_select_ << " is not among valid values" << std::endl; - std::cout << " This parameter has been set to its default value rf_port_select=A_BALANCED" << std::endl; - rf_port_select_ = std::string("A_BALANCED"); + std::cout << " This parameter has been set to its default value rf_port_select=" << default_rf_port_select << std::endl; + rf_port_select_ = default_rf_port_select; + LOG(WARNING) << "Invalid configuration value for rf_port_select parameter. Set to rf_port_select=" << default_rf_port_select; } if ((gain_mode_rx1_ != "manual") and (gain_mode_rx1_ != "slow_attack") and (gain_mode_rx1_ != "fast_attack") and (gain_mode_rx1_ != "hybrid")) @@ -357,8 +372,9 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura std::cout << "Configuration parameter gain_mode_rx1 should take one of these values:" << std::endl; std::cout << " manual, slow_attack, fast_attack, hybrid" << std::endl; std::cout << "Error: provided value gain_mode_rx1=" << gain_mode_rx1_ << " is not among valid values" << std::endl; - std::cout << " This parameter has been set to its default value gain_mode_rx1=manual" << std::endl; - gain_mode_rx1_ = std::string("manual"); + std::cout << " This parameter has been set to its default value gain_mode_rx1=" << default_gain_mode << std::endl; + gain_mode_rx1_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx1 parameter. Set to gain_mode_rx1=" << default_gain_mode; } if ((gain_mode_rx2_ != "manual") and (gain_mode_rx2_ != "slow_attack") and (gain_mode_rx2_ != "fast_attack") and (gain_mode_rx2_ != "hybrid")) @@ -366,27 +382,74 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura std::cout << "Configuration parameter gain_mode_rx2 should take one of these values:" << std::endl; std::cout << " manual, slow_attack, fast_attack, hybrid" << std::endl; std::cout << "Error: provided value gain_mode_rx2=" << gain_mode_rx2_ << " is not among valid values" << std::endl; - std::cout << " This parameter has been set to its default value gain_mode_rx2=manual" << std::endl; - gain_mode_rx2_ = std::string("manual"); + std::cout << " This parameter has been set to its default value gain_mode_rx2=" << default_gain_mode << std::endl; + gain_mode_rx2_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx2 parameter. Set to gain_mode_rx2=" << default_gain_mode; + } + + if (gain_mode_rx1_ == "manual") + { + if (rf_gain_rx1_ > 73.0 or rf_gain_rx1_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx1 should take values between -1.0 and 73 dB" << std::endl; + std::cout << "Error: provided value rf_gain_rx1=" << rf_gain_rx1_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value rf_gain_rx1=" << default_manual_gain_rx1 << std::endl; + rf_gain_rx1_ = default_manual_gain_rx1; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx1 parameter. Set to rf_gain_rx1=" << default_manual_gain_rx1; + } + } + + if (gain_mode_rx2_ == "manual") + { + if (rf_gain_rx2_ > 73.0 or rf_gain_rx2_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx2 should take values between -1.0 and 73 dB" << std::endl; + std::cout << "Error: provided value rf_gain_rx2=" << rf_gain_rx2_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value rf_gain_rx2=" << default_manual_gain_rx2 << std::endl; + rf_gain_rx2_ = default_manual_gain_rx2; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx2 parameter. Set to rf_gain_rx2=" << default_manual_gain_rx2; + } } std::cout << "LO frequency : " << freq_ << " Hz" << std::endl; - config_ad9361_rx_local(bandwidth_, - sample_rate_, - freq_, - rf_port_select_, - gain_mode_rx1_, - gain_mode_rx2_, - rf_gain_rx1_, - rf_gain_rx2_, - quadrature_, - rf_dc_, - bb_dc_); - + try + { + config_ad9361_rx_local(bandwidth_, + sample_rate_, + freq_, + rf_port_select_, + gain_mode_rx1_, + gain_mode_rx2_, + rf_gain_rx1_, + rf_gain_rx2_, + quadrature_, + rf_dc_, + bb_dc_); + } + catch (const std::runtime_error &e) + { + std::cout << "Exception cached when configuring the RX chain: " << e.what() << std::endl; + } // LOCAL OSCILLATOR DDS GENERATOR FOR DUAL FREQUENCY OPERATION if (enable_dds_lo_ == true) { - config_ad9361_lo_local(bandwidth_, + if (tx_bandwidth_ < static_cast(std::floor(static_cast(freq_rf_tx_hz_) * 1.1))) + { + std::cout << "Configuration parameter tx_bandwidth should be higher than " << static_cast(freq_rf_tx_hz_) * 1.1 << " Hz" << std::endl; + std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is lower than the minimum allowed value" << std::endl; + std::cout << " This parameter has been set to its default value tx_bandwidth=500000" << std::endl; + tx_bandwidth_ = 500000; + LOG(WARNING) << "Invalid configuration value for tx_bandwidth parameter. Set to tx_bandwidth=500000"; + } + if (tx_attenuation_db_ > 0.0 or tx_attenuation_db_ < -89.75) + { + std::cout << "Configuration parameter tx_attenuation_db should take values between 0.0 and -89.95 in 0.25 dB steps" << std::endl; + std::cout << "Error: provided value tx_attenuation_db=" << tx_attenuation_db_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value tx_attenuation_db=" << default_tx_attenuation_db << std::endl; + tx_attenuation_db_ = default_tx_attenuation_db; + LOG(WARNING) << "Invalid configuration value for tx_attenuation_db parameter. Set to tx_attenuation_db=" << default_tx_attenuation_db; + } + config_ad9361_lo_local(tx_bandwidth_, sample_rate_, freq_rf_tx_hz_, tx_attenuation_db_, @@ -394,10 +457,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura scale_dds_dbfs_); } } - if (switch_position != 0 && switch_position != 2) - { - std::cout << "SignalSource.switch_position configuration parameter must be either 0: read from file(s) via DMA, or 2: read from AD9361" << std::endl; - } + if (in_stream_ > 0) { LOG(ERROR) << "A signal source does not have an input stream"; diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h index dd807308d..8e26c4bb3 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h @@ -101,6 +101,7 @@ private: bool enable_dds_lo_; uint64_t freq_rf_tx_hz_; uint64_t freq_dds_tx_hz_; + uint64_t tx_bandwidth_; double scale_dds_dbfs_; double phase_dds_deg_; double tx_attenuation_db_; @@ -109,7 +110,7 @@ private: uint32_t out_stream_; size_t item_size_; - long samples_; + int64_t samples_; std::shared_ptr> queue_; diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index 3a83bfe31..c62acb083 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -47,6 +47,8 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration { std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/signal_source.dat"; + std::string default_gain_mode("slow attack"); + double default_tx_attenuation_db = -10.0; uri_ = configuration->property(role + ".device_address", std::string("192.168.2.1")); freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ); sample_rate_ = configuration->property(role + ".sampling_frequency", 2600000); @@ -58,8 +60,8 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration 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")); + 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_gain_rx1_ = configuration->property(role + ".gain_rx1", 64.0); rf_gain_rx2_ = configuration->property(role + ".gain_rx2", 64.0); rf_port_select_ = configuration->property(role + ".rf_port_select", std::string("A_BALANCED")); @@ -68,7 +70,7 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration filter_filename_ = configuration->property(role + ".filter_filename", std::string("")); Fpass_ = configuration->property(role + ".Fpass", 0.0); Fstop_ = configuration->property(role + ".Fstop", 0.0); - filter_auto_ = configuration->property(role + ".filter_auto", true); + filter_auto_ = configuration->property(role + ".filter_auto", false); item_type_ = configuration->property(role + ".item_type", default_item_type); samples_ = configuration->property(role + ".samples", 0); dump_ = configuration->property(role + ".dump", false); @@ -80,7 +82,8 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration 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); + tx_attenuation_db_ = configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db); + tx_bandwidth_ = configuration->property(role + ".tx_bandwidth", 500000); item_size_ = sizeof(gr_complex); @@ -92,6 +95,7 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration std::cout << "Error: provided value rf_port_select=" << rf_port_select_ << " is not among valid values" << std::endl; std::cout << " This parameter has been set to its default value rf_port_select=A_BALANCED" << std::endl; rf_port_select_ = std::string("A_BALANCED"); + LOG(WARNING) << "Invalid configuration value for rf_port_select parameter. Set to rf_port_select=A_BALANCED"; } if ((gain_mode_rx1_ != "manual") and (gain_mode_rx1_ != "slow_attack") and (gain_mode_rx1_ != "fast_attack") and (gain_mode_rx1_ != "hybrid")) @@ -99,8 +103,9 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration std::cout << "Configuration parameter gain_mode_rx1 should take one of these values:" << std::endl; std::cout << " manual, slow_attack, fast_attack, hybrid" << std::endl; std::cout << "Error: provided value gain_mode_rx1=" << gain_mode_rx1_ << " is not among valid values" << std::endl; - std::cout << " This parameter has been set to its default value gain_mode_rx1=manual" << std::endl; - gain_mode_rx1_ = std::string("manual"); + std::cout << " This parameter has been set to its default value gain_mode_rx1=" << default_gain_mode << std::endl; + gain_mode_rx1_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx1 parameter. Set to gain_mode_rx1=" << default_gain_mode; } if ((gain_mode_rx2_ != "manual") and (gain_mode_rx2_ != "slow_attack") and (gain_mode_rx2_ != "fast_attack") and (gain_mode_rx2_ != "hybrid")) @@ -108,10 +113,15 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration std::cout << "Configuration parameter gain_mode_rx2 should take one of these values:" << std::endl; std::cout << " manual, slow_attack, fast_attack, hybrid" << std::endl; std::cout << "Error: provided value gain_mode_rx2=" << gain_mode_rx2_ << " is not among valid values" << std::endl; - std::cout << " This parameter has been set to its default value gain_mode_rx2=manual" << std::endl; - gain_mode_rx2_ = std::string("manual"); + std::cout << " This parameter has been set to its default value gain_mode_rx2=" << default_gain_mode << std::endl; + gain_mode_rx2_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx1 parameter. Set to gain_mode_rx2=" << default_gain_mode; } + if (filter_auto_) + { + filter_source_ = std::string("Auto"); + } if ((filter_source_ != "Off") and (filter_source_ != "Auto") and (filter_source_ != "File") and (filter_source_ != "Design")) { std::cout << "Configuration parameter filter_source should take one of these values:" << std::endl; @@ -122,6 +132,31 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values" << std::endl; std::cout << " This parameter has been set to its default value filter_source=Off" << std::endl; filter_source_ = std::string("Off"); + LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off"; + } + + if (gain_mode_rx1_ == "manual") + { + if (rf_gain_rx1_ > 73.0 or rf_gain_rx1_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx1 should take values between -1.0 and 73 dB" << std::endl; + std::cout << "Error: provided value rf_gain_rx1=" << rf_gain_rx1_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value rf_gain_rx1=64.0" << std::endl; + rf_gain_rx1_ = 64.0; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx1 parameter. Set to rf_gain_rx1=64.0"; + } + } + + if (gain_mode_rx2_ == "manual") + { + if (rf_gain_rx2_ > 73.0 or rf_gain_rx2_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx2 should take values between -1.0 and 73 dB" << std::endl; + std::cout << "Error: provided value rf_gain_rx2=" << rf_gain_rx2_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value rf_gain_rx2=64.0" << std::endl; + rf_gain_rx2_ = 64.0; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx2 parameter. Set to rf_gain_rx2=64.0"; + } } std::cout << "device address: " << uri_ << std::endl; @@ -162,14 +197,37 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration // configure LO if (enable_dds_lo_ == true) { + if (tx_bandwidth_ < static_cast(freq_rf_tx_hz_) * 1.1) + { + std::cout << "Configuration parameter tx_bandwidth should be higher than " << static_cast(freq_rf_tx_hz_) * 1.1 << " Hz" << std::endl; + std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is lower than the minimum allowed value" << std::endl; + std::cout << " This parameter has been set to its default value tx_bandwidth=500000" << std::endl; + tx_bandwidth_ = 500000; + LOG(WARNING) << "Invalid configuration value for tx_bandwidth parameter. Set to tx_bandwidth=500000"; + } + if (tx_attenuation_db_ > 0.0 or tx_attenuation_db_ < -89.75) + { + std::cout << "Configuration parameter tx_attenuation_db should take values between 0.0 and -89.95 in 0.25 dB steps" << std::endl; + std::cout << "Error: provided value tx_attenuation_db=" << tx_attenuation_db_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value tx_attenuation_db=" << default_tx_attenuation_db << std::endl; + tx_attenuation_db_ = default_tx_attenuation_db; + LOG(WARNING) << "Invalid configuration value for tx_attenuation_db parameter. Set to tx_attenuation_db=" << default_tx_attenuation_db; + } 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_); + try + { + config_ad9361_lo_remote(uri_, + tx_bandwidth_, + sample_rate_, + freq_rf_tx_hz_, + tx_attenuation_db_, + freq_dds_tx_hz_, + scale_dds_dbfs_); + } + catch (const std::runtime_error& e) + { + std::cout << "Exception cached when configuring the TX carrier: " << e.what() << std::endl; + } } } } @@ -205,14 +263,37 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration // configure LO if (enable_dds_lo_ == true) { + if (tx_bandwidth_ < static_cast(std::floor(static_cast(freq_rf_tx_hz_) * 1.1))) + { + std::cout << "Configuration parameter tx_bandwidth should be higher than " << static_cast(freq_rf_tx_hz_) * 1.1 << " Hz" << std::endl; + std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is lower than the minimum allowed value" << std::endl; + std::cout << " This parameter has been set to its default value tx_bandwidth=500000" << std::endl; + tx_bandwidth_ = 500000; + LOG(WARNING) << "Invalid configuration value for tx_bandwidth parameter. Set to tx_bandwidth=500000"; + } + if (tx_attenuation_db_ > 0.0 or tx_attenuation_db_ < -89.75) + { + std::cout << "Configuration parameter tx_attenuation_db should take values between 0.0 and -89.95 in 0.25 dB steps" << std::endl; + std::cout << "Error: provided value tx_attenuation_db=" << tx_attenuation_db_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value tx_attenuation_db=" << default_tx_attenuation_db << std::endl; + tx_attenuation_db_ = default_tx_attenuation_db; + LOG(WARNING) << "Invalid configuration value for tx_attenuation_db parameter. Set to tx_attenuation_db=" << default_tx_attenuation_db; + } 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_); + try + { + config_ad9361_lo_remote(uri_, + tx_bandwidth_, + sample_rate_, + freq_rf_tx_hz_, + tx_attenuation_db_, + freq_dds_tx_hz_, + scale_dds_dbfs_); + } + catch (const std::runtime_error& e) + { + std::cout << "Exception cached when configuring the TX carrier: " << e.what() << std::endl; + } } } } diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h index b4d2c19f7..cc08bfc47 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h @@ -43,6 +43,7 @@ #endif #include "concurrent_queue.h" #include +#include #include #include @@ -84,11 +85,11 @@ private: std::string role_; // Front-end settings - std::string uri_; // device direction - unsigned long freq_; // frequency of local oscilator - unsigned long sample_rate_; - unsigned long bandwidth_; - unsigned long buffer_size_; // reception buffer + std::string uri_; // device direction + uint64_t freq_; // frequency of local oscilator + uint64_t sample_rate_; + uint64_t bandwidth_; + uint64_t buffer_size_; // reception buffer bool rx1_en_; bool rx2_en_; bool quadrature_; @@ -109,18 +110,19 @@ private: // DDS configuration for LO generation for external mixer bool enable_dds_lo_; - unsigned long freq_rf_tx_hz_; - unsigned long freq_dds_tx_hz_; + uint64_t freq_rf_tx_hz_; + uint64_t freq_dds_tx_hz_; double scale_dds_dbfs_; double phase_dds_deg_; double tx_attenuation_db_; + uint64_t tx_bandwidth_; unsigned int in_stream_; unsigned int out_stream_; std::string item_type_; size_t item_size_; - long samples_; + int64_t samples_; bool dump_; std::string dump_filename_; diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc index c3bcf4619..b4fcac2ba 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc @@ -43,6 +43,7 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration { std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/signal_source.dat"; + std::string default_gain_mode("slow attack"); uri_ = configuration->property(role + ".device_address", std::string("192.168.2.1")); freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ); sample_rate_ = configuration->property(role + ".sampling_frequency", 3000000); @@ -51,12 +52,12 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration quadrature_ = configuration->property(role + ".quadrature", true); rf_dc_ = configuration->property(role + ".rf_dc", true); bb_dc_ = configuration->property(role + ".bb_dc", true); - gain_mode_ = configuration->property(role + ".gain_mode", std::string("manual")); + gain_mode_ = configuration->property(role + ".gain_mode", default_gain_mode); rf_gain_ = configuration->property(role + ".gain", 50.0); filter_file_ = configuration->property(role + ".filter_file", std::string("")); - filter_auto_ = configuration->property(role + ".filter_auto", true); + filter_auto_ = configuration->property(role + ".filter_auto", false); filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); - filter_filename_ = configuration->property(role + ".filter_filename", std::string("")); + filter_filename_ = configuration->property(role + ".filter_filename", filter_file_); Fpass_ = configuration->property(role + ".Fpass", 0.0); Fstop_ = configuration->property(role + ".Fstop", 0.0); item_type_ = configuration->property(role + ".item_type", default_item_type); @@ -64,6 +65,11 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); + if (filter_auto_) + { + filter_source_ = std::string("Auto"); + } + if (item_type_ != "gr_complex") { std::cout << "Configuration error: item_type must be gr_complex" << std::endl; @@ -73,11 +79,37 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration // basic check if ((gain_mode_ != "manual") and (gain_mode_ != "slow_attack") and (gain_mode_ != "fast_attack") and (gain_mode_ != "hybrid")) { - std::cout << "Configuration parameter gain_mode_rx1 should take one of these values:" << std::endl; + std::cout << "Configuration parameter gain_mode should take one of these values:" << std::endl; std::cout << " manual, slow_attack, fast_attack, hybrid" << std::endl; std::cout << "Error: provided value gain_mode=" << gain_mode_ << " is not among valid values" << std::endl; - std::cout << " This parameter has been set to its default value gain_mode=manual" << std::endl; - gain_mode_ = std::string("manual"); + std::cout << " This parameter has been set to its default value gain_mode=" << default_gain_mode << std::endl; + gain_mode_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode parameter. Set to gain_mode=" << default_gain_mode; + } + + if (gain_mode_ == "manual") + { + if (rf_gain_ > 73.0 or rf_gain_ < -1.0) + { + std::cout << "Configuration parameter rf_gain should take values between -1.0 and 73 dB" << std::endl; + std::cout << "Error: provided value rf_gain=" << rf_gain_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value rf_gain=64.0" << std::endl; + rf_gain_ = 64.0; + LOG(WARNING) << "Invalid configuration value for rf_gain parameter. Set to rf_gain=64.0"; + } + } + + if ((filter_source_ != "Off") and (filter_source_ != "Auto") and (filter_source_ != "File") and (filter_source_ != "Design")) + { + std::cout << "Configuration parameter filter_source should take one of these values:" << std::endl; + std::cout << " Off: Disable filter" << std::endl; + std::cout << " Auto: Use auto-generated filters" << std::endl; + std::cout << " File: User-provided filter in filter_filename parameter" << std::endl; + std::cout << " Design: Create filter from Fpass, Fstop, sampling_frequency and bandwidth parameters" << std::endl; + std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value filter_source=Off" << std::endl; + filter_source_ = std::string("Off"); + LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off"; } item_size_ = sizeof(gr_complex); diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.h b/src/algorithms/signal_source/adapters/plutosdr_signal_source.h index 7c0f6a89d..4ee083ca4 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.h +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.h @@ -42,6 +42,7 @@ #endif #include "concurrent_queue.h" #include +#include #include #include @@ -85,11 +86,11 @@ private: std::string role_; // Front-end settings - std::string uri_; // device direction - unsigned long freq_; // frequency of local oscilator - unsigned long sample_rate_; - unsigned long bandwidth_; - unsigned long buffer_size_; // reception buffer + std::string uri_; // device direction + uint64_t freq_; // frequency of local oscilator + uint64_t sample_rate_; + uint64_t bandwidth_; + uint64_t buffer_size_; // reception buffer bool quadrature_; bool rf_dc_; bool bb_dc_; @@ -107,7 +108,7 @@ private: std::string item_type_; size_t item_size_; - long samples_; + int64_t samples_; bool dump_; std::string dump_filename_; diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index 7a81e6617..e778865ea 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -490,10 +490,16 @@ bool config_ad9361_lo_local(uint64_t bandwidth_, ad9361_phy = iio_context_find_device(ctx, "ad9361-phy"); int ret; // set output amplifier attenuation - ret = iio_device_attr_write_double(ad9361_phy, "out_voltage0_hardwaregain", -tx_attenuation_db_); + ret = iio_device_attr_write_double(ad9361_phy, "out_voltage0_hardwaregain", -std::abs(tx_attenuation_db_)); if (ret < 0) { - std::cout << "Failed to set out_voltage0_hardwaregain value " << -tx_attenuation_db_ << " error " << ret << std::endl; + std::cout << "Failed to set out_voltage0_hardwaregain value " << -std::abs(tx_attenuation_db_) << ". Error " << ret << std::endl; + } + // shut down signal in TX2 + ret = iio_device_attr_write_double(ad9361_phy, "out_voltage1_hardwaregain", -89.75); + if (ret < 0) + { + std::cout << "Failed to set out_voltage1_hardwaregain value -89.75 dB. Error " << ret << std::endl; } struct iio_device *dds; @@ -625,12 +631,18 @@ bool config_ad9361_lo_remote(const std::string &remote_host, ad9361_phy = iio_context_find_device(ctx, "ad9361-phy"); int ret; // set output amplifier attenuation - ret = iio_device_attr_write_double(ad9361_phy, "out_voltage0_hardwaregain", -tx_attenuation_db_); + ret = iio_device_attr_write_double(ad9361_phy, "out_voltage0_hardwaregain", -std::abs(tx_attenuation_db_)); if (ret < 0) { - std::cout << "Failed to set out_voltage0_hardwaregain value " << -tx_attenuation_db_ << " error " << ret << std::endl; + std::cout << "Failed to set out_voltage0_hardwaregain value " << -std::abs(tx_attenuation_db_) << ". Error " << ret << std::endl; } + // shut down signal in TX2 + ret = iio_device_attr_write_double(ad9361_phy, "out_voltage1_hardwaregain", -89.75); + if (ret < 0) + { + std::cout << "Failed to set out_voltage1_hardwaregain value -89.75 dB. Error " << ret << std::endl; + } struct iio_device *dds; dds = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc"); struct iio_channel *dds_channel0_I; From bdabbf7f85158b54df363e1b21f0adc461c7b524 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 8 Oct 2019 12:57:37 +0200 Subject: [PATCH 02/19] Implement phase_dds_deg parameter, fix guard for tx_bandwidth --- .../adapters/ad9361_fpga_signal_source.cc | 46 +++++++++++-------- .../adapters/ad9361_fpga_signal_source.h | 1 - .../adapters/fmcomms2_signal_source.cc | 21 +++++---- .../signal_source/libs/ad9361_manager.cc | 14 +++--- .../signal_source/libs/ad9361_manager.h | 6 ++- 5 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc index 4a5febc21..fffef1468 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc @@ -37,13 +37,14 @@ #include "configuration_interface.h" #include #include -#include // for abs -#include -#include // for open, O_WRONLY -#include // for std::ifstream -#include // for cout, endl -#include // for string manipulation -#include // for write +#include // for max +#include // for abs +#include // for exceptions +#include // for open, O_WRONLY +#include // for std::ifstream +#include // for cout, endl +#include // for string manipulation +#include // for write #include #include @@ -299,14 +300,13 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura rf_port_select_ = configuration->property(role + ".rf_port_select", default_rf_port_select); filter_file_ = configuration->property(role + ".filter_file", std::string("")); filter_auto_ = configuration->property(role + ".filter_auto", false); - samples_ = configuration->property(role + ".samples", 0); 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); + freq_rf_tx_hz_ = configuration->property(role + ".freq_rf_tx_hz", GPS_L1_FREQ_HZ - GPS_L2_FREQ_HZ - freq_dds_tx_hz_); 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); tx_bandwidth_ = configuration->property(role + ".tx_bandwidth", 500000); + phase_dds_deg_ = configuration->property(role + ".phase_dds_deg", 0.0); // turn switch to A/D position std::string default_device_name = "/dev/uio1"; @@ -433,10 +433,10 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura // LOCAL OSCILLATOR DDS GENERATOR FOR DUAL FREQUENCY OPERATION if (enable_dds_lo_ == true) { - if (tx_bandwidth_ < static_cast(std::floor(static_cast(freq_rf_tx_hz_) * 1.1))) + if (tx_bandwidth_ < static_cast(std::floor(static_cast(freq_dds_tx_hz_) * 1.1)) or (tx_bandwidth_ < 200000) or (tx_bandwidth_ > 1000000)) { - std::cout << "Configuration parameter tx_bandwidth should be higher than " << static_cast(freq_rf_tx_hz_) * 1.1 << " Hz" << std::endl; - std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is lower than the minimum allowed value" << std::endl; + std::cout << "Configuration parameter tx_bandwidth value should be between " << std::max(static_cast(freq_dds_tx_hz_) * 1.1, 200000.0) << " and 1000000 Hz" << std::endl; + std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is not among valid values" << std::endl; std::cout << " This parameter has been set to its default value tx_bandwidth=500000" << std::endl; tx_bandwidth_ = 500000; LOG(WARNING) << "Invalid configuration value for tx_bandwidth parameter. Set to tx_bandwidth=500000"; @@ -449,12 +449,20 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura tx_attenuation_db_ = default_tx_attenuation_db; LOG(WARNING) << "Invalid configuration value for tx_attenuation_db parameter. Set to tx_attenuation_db=" << default_tx_attenuation_db; } - config_ad9361_lo_local(tx_bandwidth_, - sample_rate_, - freq_rf_tx_hz_, - tx_attenuation_db_, - freq_dds_tx_hz_, - scale_dds_dbfs_); + try + { + config_ad9361_lo_local(tx_bandwidth_, + sample_rate_, + freq_rf_tx_hz_, + tx_attenuation_db_, + freq_dds_tx_hz_, + scale_dds_dbfs_, + phase_dds_deg_); + } + catch (const std::runtime_error &e) + { + std::cout << "Exception cached when configuring the TX carrier: " << e.what() << std::endl; + } } } diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h index 8e26c4bb3..a68a3e6b4 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h @@ -110,7 +110,6 @@ private: uint32_t out_stream_; size_t item_size_; - int64_t samples_; std::shared_ptr> queue_; diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index c62acb083..08205ad1f 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -36,6 +36,7 @@ #include "configuration_interface.h" #include "gnss_sdr_valve.h" #include +#include // for max #include #include #include @@ -78,8 +79,8 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration // 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); + freq_rf_tx_hz_ = configuration->property(role + ".freq_rf_tx_hz", GPS_L1_FREQ_HZ - GPS_L2_FREQ_HZ - freq_dds_tx_hz_); 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", default_tx_attenuation_db); @@ -197,10 +198,10 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration // configure LO if (enable_dds_lo_ == true) { - if (tx_bandwidth_ < static_cast(freq_rf_tx_hz_) * 1.1) + if (tx_bandwidth_ < static_cast(std::floor(static_cast(freq_dds_tx_hz_) * 1.1)) or (tx_bandwidth_ < 200000) or (tx_bandwidth_ > 1000000)) { - std::cout << "Configuration parameter tx_bandwidth should be higher than " << static_cast(freq_rf_tx_hz_) * 1.1 << " Hz" << std::endl; - std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is lower than the minimum allowed value" << std::endl; + std::cout << "Configuration parameter tx_bandwidth value should be between " << std::max(static_cast(freq_dds_tx_hz_) * 1.1, 200000.0) << " and 1000000 Hz" << std::endl; + std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is not among valid values" << std::endl; std::cout << " This parameter has been set to its default value tx_bandwidth=500000" << std::endl; tx_bandwidth_ = 500000; LOG(WARNING) << "Invalid configuration value for tx_bandwidth parameter. Set to tx_bandwidth=500000"; @@ -222,7 +223,8 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration freq_rf_tx_hz_, tx_attenuation_db_, freq_dds_tx_hz_, - scale_dds_dbfs_); + scale_dds_dbfs_, + phase_dds_deg_); } catch (const std::runtime_error& e) { @@ -263,10 +265,10 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration // configure LO if (enable_dds_lo_ == true) { - if (tx_bandwidth_ < static_cast(std::floor(static_cast(freq_rf_tx_hz_) * 1.1))) + if (tx_bandwidth_ < static_cast(std::floor(static_cast(freq_dds_tx_hz_) * 1.1)) or (tx_bandwidth_ < 200000) or (tx_bandwidth_ > 1000000)) { - std::cout << "Configuration parameter tx_bandwidth should be higher than " << static_cast(freq_rf_tx_hz_) * 1.1 << " Hz" << std::endl; - std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is lower than the minimum allowed value" << std::endl; + std::cout << "Configuration parameter tx_bandwidth value should be between " << std::max(static_cast(freq_dds_tx_hz_) * 1.1, 200000.0) << " and 1000000 Hz" << std::endl; + std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is not among valid values" << std::endl; std::cout << " This parameter has been set to its default value tx_bandwidth=500000" << std::endl; tx_bandwidth_ = 500000; LOG(WARNING) << "Invalid configuration value for tx_bandwidth parameter. Set to tx_bandwidth=500000"; @@ -288,7 +290,8 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration freq_rf_tx_hz_, tx_attenuation_db_, freq_dds_tx_hz_, - scale_dds_dbfs_); + scale_dds_dbfs_, + phase_dds_deg_); } catch (const std::runtime_error& e) { diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index e778865ea..ffe927d3e 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -448,7 +448,8 @@ bool config_ad9361_lo_local(uint64_t bandwidth_, uint64_t freq_rf_tx_hz_, double tx_attenuation_db_, int64_t freq_dds_tx_hz_, - double scale_dds_dbfs_) + double scale_dds_dbfs_, + double phase_dds_deg_) { // TX stream config std::cout << "Start of AD9361 TX Local Oscillator DDS configuration\n"; @@ -529,13 +530,13 @@ bool config_ad9361_lo_local(uint64_t bandwidth_, std::cout << "Failed to set TX DDS frequency Q: " << ret << std::endl; } - ret = iio_channel_attr_write_double(dds_channel0_I, "phase", 0.0); + ret = iio_channel_attr_write_double(dds_channel0_I, "phase", phase_dds_deg_ * 1000.0); if (ret < 0) { std::cout << "Failed to set TX DDS phase I: " << ret << std::endl; } - ret = iio_channel_attr_write_double(dds_channel0_Q, "phase", 270000.0); + ret = iio_channel_attr_write_double(dds_channel0_Q, "phase", phase_dds_deg_ * 1000.0 + 270000.0); if (ret < 0) { std::cout << "Failed to set TX DDS phase Q: " << ret << std::endl; @@ -589,7 +590,8 @@ bool config_ad9361_lo_remote(const std::string &remote_host, uint64_t freq_rf_tx_hz_, double tx_attenuation_db_, int64_t freq_dds_tx_hz_, - double scale_dds_dbfs_) + double scale_dds_dbfs_, + double phase_dds_deg_) { // TX stream config std::cout << "Start of AD9361 TX Local Oscillator DDS configuration\n"; @@ -670,13 +672,13 @@ bool config_ad9361_lo_remote(const std::string &remote_host, std::cout << "Failed to set TX DDS frequency Q: " << ret << std::endl; } - ret = iio_channel_attr_write_double(dds_channel0_I, "phase", 0.0); + ret = iio_channel_attr_write_double(dds_channel0_I, "phase", phase_dds_deg_ * 1000.0); if (ret < 0) { std::cout << "Failed to set TX DDS phase I: " << ret << std::endl; } - ret = iio_channel_attr_write_double(dds_channel0_Q, "phase", 270000.0); + ret = iio_channel_attr_write_double(dds_channel0_Q, "phase", phase_dds_deg_ * 1000.0 + 270000.0); if (ret < 0) { std::cout << "Failed to set TX DDS phase Q: " << ret << std::endl; diff --git a/src/algorithms/signal_source/libs/ad9361_manager.h b/src/algorithms/signal_source/libs/ad9361_manager.h index 50ab56d3b..1d9bd42d0 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.h +++ b/src/algorithms/signal_source/libs/ad9361_manager.h @@ -115,7 +115,8 @@ bool config_ad9361_lo_local(uint64_t bandwidth_, uint64_t freq_rf_tx_hz_, double tx_attenuation_db_, int64_t freq_dds_tx_hz_, - double scale_dds_dbfs_); + double scale_dds_dbfs_, + double phase_dds_deg_); bool config_ad9361_lo_remote(const std::string &remote_host, uint64_t bandwidth_, @@ -123,7 +124,8 @@ bool config_ad9361_lo_remote(const std::string &remote_host, uint64_t freq_rf_tx_hz_, double tx_attenuation_db_, int64_t freq_dds_tx_hz_, - double scale_dds_dbfs_); + double scale_dds_dbfs_, + double phase_dds_deg_); bool ad9361_disable_lo_remote(const std::string &remote_host); From daa30c992c506dcead232025007050c7ef368ff1 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 8 Oct 2019 14:47:28 +0200 Subject: [PATCH 03/19] Remove unused parameters --- .../signal_source/adapters/ad9361_fpga_signal_source.cc | 3 --- .../signal_source/adapters/ad9361_fpga_signal_source.h | 3 --- 2 files changed, 6 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc index fffef1468..2be133ced 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc @@ -287,9 +287,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ); sample_rate_ = configuration->property(role + ".sampling_frequency", 12500000); bandwidth_ = configuration->property(role + ".bandwidth", 12500000); - rx1_en_ = configuration->property(role + ".rx1_enable", true); - rx2_en_ = configuration->property(role + ".rx2_enable", true); - buffer_size_ = configuration->property(role + ".buffer_size", 0xA0000); quadrature_ = configuration->property(role + ".quadrature", true); rf_dc_ = configuration->property(role + ".rf_dc", true); bb_dc_ = configuration->property(role + ".bb_dc", true); diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h index a68a3e6b4..ca41a0fe8 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h @@ -83,9 +83,6 @@ private: uint64_t freq_; // frequency of local oscillator uint64_t sample_rate_; uint64_t bandwidth_; - uint64_t buffer_size_; // reception buffer - bool rx1_en_; - bool rx2_en_; bool quadrature_; bool rf_dc_; bool bb_dc_; From 4208ffb4fbb4c7702be6ce4c627fc20242262f64 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 8 Oct 2019 14:55:16 +0200 Subject: [PATCH 04/19] Work in the FIR filter --- .../signal_source/libs/ad9361_manager.cc | 77 +++++++++++++++---- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index 7a81e6617..20c1fc696 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -325,10 +325,6 @@ bool config_ad9361_rx_remote(const std::string &remote_host, // 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 REMOTE context in host " << remote_host << std::endl; struct iio_context *ctx; @@ -358,11 +354,56 @@ bool config_ad9361_rx_remote(const std::string &remote_host, throw std::runtime_error("AD9361 IIO No rx dev found"); }; + struct iio_device *ad9361_phy; + ad9361_phy = iio_context_find_device(ctx, "ad9361-phy"); + int ret; + std::cout << "* Configuring AD9361 for streaming\n"; - if (!cfg_ad9361_streaming_ch(ctx, &rxcfg, RX, 0)) + + if (filter_source_ == "Off") { - std::cout << "RX port 0 not found\n"; - throw std::runtime_error("AD9361 IIO RX port 0 not found"); + 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.) + + 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"); + } + } + else if (filter_source_ == "Auto") + { + ret = ad9361_set_bb_rate(ad9361_phy, sample_rate_); + if (ret) + { + throw std::runtime_error("Unable to set BB rate"); + // set bw + //params.push_back("in_voltage_rf_bandwidth=" + boost::to_string(bandwidth)); + } + // in_voltage0_rf_port_select + } + else if (filter_source_ == "File") + { + if (!load_fir_filter(filter_filename_, ad9361_phy)) + { + throw std::runtime_error("Unable to load filter file"); + } + } + else if (filter_source_ == "Design") + { + ret = ad9361_set_bb_rate_custom_filter_manual( + ad9361_phy, sample_rate_, Fpass_, Fstop_, bandwidth_, bandwidth_); + if (ret) + { + throw std::runtime_error("Unable to set BB rate"); + } + } + else + { + throw std::runtime_error("Unknown filter configuration"); } std::cout << "* Initializing AD9361 IIO streaming channels\n"; @@ -382,9 +423,6 @@ bool config_ad9361_rx_remote(const std::string &remote_host, 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) { @@ -425,17 +463,24 @@ bool config_ad9361_rx_remote(const std::string &remote_host, { std::cout << "Failed to set in_voltage1_gain_control_mode: " << ret << std::endl; } - ret = iio_device_attr_write_double(ad9361_phy, "in_voltage0_hardwaregain", rf_gain_rx1_); - if (ret < 0) + if (gain_mode_rx1_ == "manual") { - std::cout << "Failed to set in_voltage0_hardwaregain: " << ret << std::endl; + ret = iio_device_attr_write_double(ad9361_phy, "in_voltage0_hardwaregain", rf_gain_rx1_); + if (ret < 0) + { + std::cout << "Failed to set in_voltage0_hardwaregain: " << ret << std::endl; + } } - ret = iio_device_attr_write_double(ad9361_phy, "in_voltage1_hardwaregain", rf_gain_rx2_); - if (ret < 0) + if (gain_mode_rx2_ == "manual") { - std::cout << "Failed to set in_voltage1_hardwaregain: " << ret << std::endl; + ret = iio_device_attr_write_double(ad9361_phy, "in_voltage1_hardwaregain", rf_gain_rx2_); + if (ret < 0) + { + std::cout << "Failed to set in_voltage1_hardwaregain: " << ret << std::endl; + } } + std::cout << "End of AD9361 RX configuration.\n"; iio_context_destroy(ctx); From 0dbba0500d1ad6fd21869af74234ce7bbfb3384e Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 8 Oct 2019 16:38:30 +0200 Subject: [PATCH 05/19] Add more parameter guards --- .../adapters/ad9361_fpga_signal_source.cc | 13 ++++++++- .../adapters/fmcomms2_signal_source.cc | 27 ++++++++++++++----- .../adapters/plutosdr_signal_source.cc | 23 +++++++++++----- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc index 2be133ced..353ed1dc0 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc @@ -283,10 +283,11 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura double default_tx_attenuation_db = -10.0; double default_manual_gain_rx1 = 64.0; double default_manual_gain_rx2 = 64.0; + uint64_t default_bandwidth = 12500000; std::string default_rf_port_select("A_BALANCED"); freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ); sample_rate_ = configuration->property(role + ".sampling_frequency", 12500000); - bandwidth_ = configuration->property(role + ".bandwidth", 12500000); + bandwidth_ = configuration->property(role + ".bandwidth", default_bandwidth); quadrature_ = configuration->property(role + ".quadrature", true); rf_dc_ = configuration->property(role + ".rf_dc", true); bb_dc_ = configuration->property(role + ".bb_dc", true); @@ -297,6 +298,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura rf_port_select_ = configuration->property(role + ".rf_port_select", default_rf_port_select); filter_file_ = configuration->property(role + ".filter_file", std::string("")); filter_auto_ = configuration->property(role + ".filter_auto", false); + enable_dds_lo_ = configuration->property(role + ".enable_dds_lo", false); freq_dds_tx_hz_ = configuration->property(role + ".freq_dds_tx_hz", 1000); freq_rf_tx_hz_ = configuration->property(role + ".freq_rf_tx_hz", GPS_L1_FREQ_HZ - GPS_L2_FREQ_HZ - freq_dds_tx_hz_); @@ -408,6 +410,15 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura } } + if (bandwidth_ < 200000 or bandwidth_ > 56000000) + { + std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz" << std::endl; + std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value bandwidth=" << default_bandwidth << std::endl; + bandwidth_ = default_bandwidth; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=" << default_bandwidth; + } + std::cout << "LO frequency : " << freq_ << " Hz" << std::endl; try { diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index 08205ad1f..84b73a203 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -67,11 +67,19 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration rf_gain_rx2_ = configuration->property(role + ".gain_rx2", 64.0); rf_port_select_ = configuration->property(role + ".rf_port_select", std::string("A_BALANCED")); filter_file_ = configuration->property(role + ".filter_file", std::string("")); - filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); - filter_filename_ = configuration->property(role + ".filter_filename", std::string("")); + filter_auto_ = configuration->property(role + ".filter_auto", false); + if (filter_auto_) + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Auto")); + } + else + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); + } + filter_filename_ = configuration->property(role + ".filter_filename", filter_file_); Fpass_ = configuration->property(role + ".Fpass", 0.0); Fstop_ = configuration->property(role + ".Fstop", 0.0); - filter_auto_ = configuration->property(role + ".filter_auto", false); + item_type_ = configuration->property(role + ".item_type", default_item_type); samples_ = configuration->property(role + ".samples", 0); dump_ = configuration->property(role + ".dump", false); @@ -119,10 +127,6 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration LOG(WARNING) << "Invalid configuration value for gain_mode_rx1 parameter. Set to gain_mode_rx2=" << default_gain_mode; } - if (filter_auto_) - { - filter_source_ = std::string("Auto"); - } if ((filter_source_ != "Off") and (filter_source_ != "Auto") and (filter_source_ != "File") and (filter_source_ != "Design")) { std::cout << "Configuration parameter filter_source should take one of these values:" << std::endl; @@ -160,6 +164,15 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration } } + if (bandwidth_ < 200000 or bandwidth_ > 56000000) + { + std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz" << std::endl; + std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value bandwidth=2000000" << std::endl; + bandwidth_ = 2000000; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=2000000"; + } + std::cout << "device address: " << uri_ << std::endl; std::cout << "LO frequency : " << freq_ << " Hz" << std::endl; std::cout << "sample rate: " << sample_rate_ << " Hz" << std::endl; diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc index b4fcac2ba..d6ed8cf6e 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc @@ -56,7 +56,14 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration rf_gain_ = configuration->property(role + ".gain", 50.0); filter_file_ = configuration->property(role + ".filter_file", std::string("")); filter_auto_ = configuration->property(role + ".filter_auto", false); - filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); + if (filter_auto_) + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Auto")); + } + else + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); + } filter_filename_ = configuration->property(role + ".filter_filename", filter_file_); Fpass_ = configuration->property(role + ".Fpass", 0.0); Fstop_ = configuration->property(role + ".Fstop", 0.0); @@ -65,11 +72,6 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); - if (filter_auto_) - { - filter_source_ = std::string("Auto"); - } - if (item_type_ != "gr_complex") { std::cout << "Configuration error: item_type must be gr_complex" << std::endl; @@ -112,6 +114,15 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off"; } + if (bandwidth_ < 200000 or bandwidth_ > 56000000) + { + std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz" << std::endl; + std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value bandwidth=2000000" << std::endl; + bandwidth_ = 2000000; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=2000000"; + } + item_size_ = sizeof(gr_complex); std::cout << "device address: " << uri_ << std::endl; From 9f8dbb14f94f7df2b520529ddb3baa9974676dab Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 8 Oct 2019 16:38:30 +0200 Subject: [PATCH 06/19] Add more parameter guards --- .../adapters/ad9361_fpga_signal_source.cc | 13 ++++++++- .../adapters/fmcomms2_signal_source.cc | 27 ++++++++++++++----- .../adapters/plutosdr_signal_source.cc | 23 +++++++++++----- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc index 2be133ced..353ed1dc0 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc @@ -283,10 +283,11 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura double default_tx_attenuation_db = -10.0; double default_manual_gain_rx1 = 64.0; double default_manual_gain_rx2 = 64.0; + uint64_t default_bandwidth = 12500000; std::string default_rf_port_select("A_BALANCED"); freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ); sample_rate_ = configuration->property(role + ".sampling_frequency", 12500000); - bandwidth_ = configuration->property(role + ".bandwidth", 12500000); + bandwidth_ = configuration->property(role + ".bandwidth", default_bandwidth); quadrature_ = configuration->property(role + ".quadrature", true); rf_dc_ = configuration->property(role + ".rf_dc", true); bb_dc_ = configuration->property(role + ".bb_dc", true); @@ -297,6 +298,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura rf_port_select_ = configuration->property(role + ".rf_port_select", default_rf_port_select); filter_file_ = configuration->property(role + ".filter_file", std::string("")); filter_auto_ = configuration->property(role + ".filter_auto", false); + enable_dds_lo_ = configuration->property(role + ".enable_dds_lo", false); freq_dds_tx_hz_ = configuration->property(role + ".freq_dds_tx_hz", 1000); freq_rf_tx_hz_ = configuration->property(role + ".freq_rf_tx_hz", GPS_L1_FREQ_HZ - GPS_L2_FREQ_HZ - freq_dds_tx_hz_); @@ -408,6 +410,15 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura } } + if (bandwidth_ < 200000 or bandwidth_ > 56000000) + { + std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz" << std::endl; + std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value bandwidth=" << default_bandwidth << std::endl; + bandwidth_ = default_bandwidth; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=" << default_bandwidth; + } + std::cout << "LO frequency : " << freq_ << " Hz" << std::endl; try { diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index 08205ad1f..84b73a203 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -67,11 +67,19 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration rf_gain_rx2_ = configuration->property(role + ".gain_rx2", 64.0); rf_port_select_ = configuration->property(role + ".rf_port_select", std::string("A_BALANCED")); filter_file_ = configuration->property(role + ".filter_file", std::string("")); - filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); - filter_filename_ = configuration->property(role + ".filter_filename", std::string("")); + filter_auto_ = configuration->property(role + ".filter_auto", false); + if (filter_auto_) + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Auto")); + } + else + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); + } + filter_filename_ = configuration->property(role + ".filter_filename", filter_file_); Fpass_ = configuration->property(role + ".Fpass", 0.0); Fstop_ = configuration->property(role + ".Fstop", 0.0); - filter_auto_ = configuration->property(role + ".filter_auto", false); + item_type_ = configuration->property(role + ".item_type", default_item_type); samples_ = configuration->property(role + ".samples", 0); dump_ = configuration->property(role + ".dump", false); @@ -119,10 +127,6 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration LOG(WARNING) << "Invalid configuration value for gain_mode_rx1 parameter. Set to gain_mode_rx2=" << default_gain_mode; } - if (filter_auto_) - { - filter_source_ = std::string("Auto"); - } if ((filter_source_ != "Off") and (filter_source_ != "Auto") and (filter_source_ != "File") and (filter_source_ != "Design")) { std::cout << "Configuration parameter filter_source should take one of these values:" << std::endl; @@ -160,6 +164,15 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration } } + if (bandwidth_ < 200000 or bandwidth_ > 56000000) + { + std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz" << std::endl; + std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value bandwidth=2000000" << std::endl; + bandwidth_ = 2000000; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=2000000"; + } + std::cout << "device address: " << uri_ << std::endl; std::cout << "LO frequency : " << freq_ << " Hz" << std::endl; std::cout << "sample rate: " << sample_rate_ << " Hz" << std::endl; diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc index b4fcac2ba..d6ed8cf6e 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc @@ -56,7 +56,14 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration rf_gain_ = configuration->property(role + ".gain", 50.0); filter_file_ = configuration->property(role + ".filter_file", std::string("")); filter_auto_ = configuration->property(role + ".filter_auto", false); - filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); + if (filter_auto_) + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Auto")); + } + else + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); + } filter_filename_ = configuration->property(role + ".filter_filename", filter_file_); Fpass_ = configuration->property(role + ".Fpass", 0.0); Fstop_ = configuration->property(role + ".Fstop", 0.0); @@ -65,11 +72,6 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); - if (filter_auto_) - { - filter_source_ = std::string("Auto"); - } - if (item_type_ != "gr_complex") { std::cout << "Configuration error: item_type must be gr_complex" << std::endl; @@ -112,6 +114,15 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off"; } + if (bandwidth_ < 200000 or bandwidth_ > 56000000) + { + std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz" << std::endl; + std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value bandwidth=2000000" << std::endl; + bandwidth_ = 2000000; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=2000000"; + } + item_size_ = sizeof(gr_complex); std::cout << "device address: " << uri_ << std::endl; From 09078b6486fe4c5dd624a3e32ab7fbeaa55e89f6 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 8 Oct 2019 19:34:18 +0200 Subject: [PATCH 07/19] Implement more conf options for AD9361 FIR filters, work in progress --- CMakeLists.txt | 8 ++ cmake/Modules/FindLIBAD9361.cmake | 124 +++++++++++++++++ .../signal_source/libs/CMakeLists.txt | 2 + .../signal_source/libs/ad9361_manager.cc | 130 +++++++++++++++--- .../signal_source/libs/ad9361_manager.h | 2 + 5 files changed, 247 insertions(+), 19 deletions(-) create mode 100644 cmake/Modules/FindLIBAD9361.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 332f34e53..3a93d2cf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2286,6 +2286,14 @@ else() TYPE OPTIONAL ) endif() +find_package(LIBAD9361) +set_package_properties(LIBAD9361 PROPERTIES + PURPOSE "Used for configuring the AD9361 chipset" + TYPE OPTIONAL +) +if(NOT LIBAD9361_FOUND) + set(GRIIO_FOUND FALSE) +endif() if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) if(NOT GRIIO_FOUND) message(STATUS "gnuradio-iio not found, its installation is required.") diff --git a/cmake/Modules/FindLIBAD9361.cmake b/cmake/Modules/FindLIBAD9361.cmake new file mode 100644 index 000000000..a37671184 --- /dev/null +++ b/cmake/Modules/FindLIBAD9361.cmake @@ -0,0 +1,124 @@ +# Copyright (C) 2011-2019 (see AUTHORS file for a list of contributors) +# +# 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 . + +# +# Provides the following imported target: +# Iio::iio +# + +if(NOT COMMAND feature_summary) + include(FeatureSummary) +endif() + +set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE) +include(FindPkgConfig) +pkg_check_modules(PC_LIBAD9361 libad9361) + +find_path( + LIBAD9361_INCLUDE_DIRS + NAMES ad9361.h + HINTS ${PC_LIBAD9361_INCLUDEDIR} + PATHS /usr/include + /usr/local/include + /opt/local/include + ${CMAKE_INSTALL_PREFIX}/include + ${LIBAD9361_ROOT}/include + $ENV{LIBAD9361_ROOT}/include + $ENV{LIBAD9361_DIR}/include +) + +find_library( + LIBAD9361_LIBRARIES + NAMES ad9361 + HINTS ${PC_LIBAD9361_LIBDIR} + PATHS /usr/lib + /usr/lib64 + /usr/lib/x86_64-linux-gnu + /usr/lib/i386-linux-gnu + /usr/lib/alpha-linux-gnu + /usr/lib/aarch64-linux-gnu + /usr/lib/arm-linux-gnueabi + /usr/lib/arm-linux-gnueabihf + /usr/lib/hppa-linux-gnu + /usr/lib/i686-gnu + /usr/lib/i686-linux-gnu + /usr/lib/x86_64-kfreebsd-gnu + /usr/lib/i686-kfreebsd-gnu + /usr/lib/m68k-linux-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/mipsel-linux-gnu + /usr/lib/powerpc-linux-gnu + /usr/lib/powerpc-linux-gnuspe + /usr/lib/powerpc64-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/lib/sparc64-linux-gnu + /usr/lib/x86_64-linux-gnux32 + /usr/lib/sh4-linux-gnu + /usr/lib/riscv64-linux-gnu + /usr/local/lib + /usr/local/lib64 + /opt/local/lib + /Library/Frameworks/iio.framework/ + ${CMAKE_INSTALL_PREFIX}/lib + ${CMAKE_INSTALL_PREFIX}/lib64 + ${LIBAD9361_ROOT}/lib + $ENV{LIBAD9361_ROOT}/lib + ${LIBAD9361_ROOT}/lib64 + $ENV{LIBAD9361_ROOT}/lib64 + $ENV{LIBAD9361_DIR}/lib +) + +if(LIBAD9361_LIBRARIES AND APPLE) + if(LIBAD9361_LIBRARIES MATCHES "framework") + set(LIBAD9361_LIBRARIES ${LIBAD9361_LIBRARIES}/ad9361) + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LIBAD9361 DEFAULT_MSG LIBAD9361_LIBRARIES LIBAD9361_INCLUDE_DIRS) + +if(PC_LIBAD9361_VERSION) + set(LIBAD9361_VERSION ${PC_LIBAD9361_VERSION}) +endif() + +if(LIBAD9361_FOUND AND LIBAD9361_VERSION) + set_package_properties(LIBAD9361 PROPERTIES + DESCRIPTION "A library for interfacing with AD936X transceivers (found: v${LIBAD9361_VERSION})" + ) +else() + set_package_properties(LIBAD9361 PROPERTIES + DESCRIPTION "A library for interfacing with AD936X transceivers" + ) +endif() + +set_package_properties(LIBAD9361 PROPERTIES + URL "https://github.com/analogdevicesinc/libad9361-iio" +) + +if(LIBAD9361_FOUND AND NOT TARGET Iio::ad9361) + add_library(Iio::ad9361 SHARED IMPORTED) + set_target_properties(Iio::ad9361 PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${LIBAD9361_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${LIBAD9361_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${LIBAD9361_LIBRARIES}" + ) +endif() + +mark_as_advanced(LIBAD9361_LIBRARIES LIBAD9361_INCLUDE_DIRS) diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index 98fdbf7cd..48f8edb74 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -67,6 +67,8 @@ if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) target_link_libraries(signal_source_libs PUBLIC Iio::iio + PRIVATE + Iio::ad9361 ) endif() diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index c016c95ed..4a7611ef8 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -31,9 +31,12 @@ */ #include "ad9361_manager.h" #include +#include #include +#include // for ifstream #include #include +#include /* check return value of attr_write function */ @@ -322,9 +325,10 @@ bool config_ad9361_rx_remote(const std::string &remote_host, bool rfdc_, bool bbdc_) { + std::string filter_source_("Off"); + float Fpass_ = 0.0, Fstop_ = 0.0; + std::string filter_filename_; // RX stream config - // Stream configurations - struct stream_cfg rxcfg; std::cout << "AD9361 Acquiring IIO REMOTE context in host " << remote_host << std::endl; struct iio_context *ctx; @@ -354,19 +358,32 @@ bool config_ad9361_rx_remote(const std::string &remote_host, throw std::runtime_error("AD9361 IIO No rx dev found"); }; + std::cout << "* Configuring AD9361 for streaming\n"; + struct iio_device *ad9361_phy; ad9361_phy = iio_context_find_device(ctx, "ad9361-phy"); int ret; - std::cout << "* Configuring AD9361 for streaming\n"; + 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"); + } if (filter_source_ == "Off") { 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.) + rxcfg.bw_hz = bandwidth_; + rxcfg.fs_hz = sample_rate_; + rxcfg.lo_hz = freq_; + rxcfg.rfport = rf_port_select_.c_str(); if (!cfg_ad9361_streaming_ch(ctx, &rxcfg, RX, 0)) { @@ -383,14 +400,41 @@ bool config_ad9361_rx_remote(const std::string &remote_host, // set bw //params.push_back("in_voltage_rf_bandwidth=" + boost::to_string(bandwidth)); } + //wr_ch_str(rx0_i, "rf_port_select", rf_port_select_.c_str()); + ret = iio_device_attr_write(ad9361_phy, "in_voltage0_rf_port_select", rf_port_select_.c_str()); + if (ret) + { + throw std::runtime_error("Unable to set rf_port_select"); + } + wr_ch_lli(rx0_i, "rf_bandwidth", bandwidth_); + + //if (!get_lo_chan(ctx, "RX", &chn)) + // { + // return false; + // } + //wr_ch_lli(chn, "frequency", freq_); // in_voltage0_rf_port_select } else if (filter_source_ == "File") { - if (!load_fir_filter(filter_filename_, ad9361_phy)) + try { - throw std::runtime_error("Unable to load filter file"); + if (!load_fir_filter(filter_filename_, ad9361_phy)) + { + throw std::runtime_error("Unable to load filter file"); + } } + catch (const std::runtime_error &e) + { + std::cout << "Exception cached when configuring the RX FIR filter: " << e.what() << std::endl; + } + ret = iio_device_attr_write(ad9361_phy, "in_voltage0_rf_port_select", rf_port_select_.c_str()); + if (ret) + { + throw std::runtime_error("Unable to set rf_port_select"); + } + wr_ch_lli(rx0_i, "rf_bandwidth", bandwidth_); + wr_ch_lli(rx0_i, "frequency", freq_); } else if (filter_source_ == "Design") { @@ -400,23 +444,27 @@ bool config_ad9361_rx_remote(const std::string &remote_host, { throw std::runtime_error("Unable to set BB rate"); } + ret = iio_device_attr_write(ad9361_phy, "in_voltage0_rf_port_select", rf_port_select_.c_str()); + if (ret) + { + throw std::runtime_error("Unable to set rf_port_select"); + } + wr_ch_lli(rx0_i, "rf_bandwidth", bandwidth_); + wr_ch_lli(rx0_i, "frequency", freq_); } else { throw std::runtime_error("Unknown filter configuration"); } - std::cout << "* Initializing AD9361 IIO streaming channels\n"; - if (!get_ad9361_stream_ch(ctx, RX, rx, 0, &rx0_i)) + // Filters can only be disabled after the sample rate has been set + if (filter_source_ == "Off") { - 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"); + ret = ad9361_set_trx_fir_enable(ad9361_phy, false); + if (ret) + { + throw std::runtime_error("Unable to disable filters"); + } } std::cout << "* Enabling IIO streaming channels\n"; @@ -853,3 +901,47 @@ bool ad9361_disable_lo_local() return true; } + + +bool load_fir_filter( + std::string &filter, struct iio_device *phy) +{ + if (filter.empty() || !iio_device_find_attr(phy, "filter_fir_config")) + { + return false; + } + + std::ifstream ifs(filter.c_str(), std::ifstream::binary); + if (!ifs) + { + return false; + } + + /* Here, we verify that the filter file contains data for both RX+TX. */ + { + char buf[256]; + do + { + ifs.getline(buf, sizeof(buf)); + } + while (!(buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9'))); + + std::string line(buf); + if (line.find(',') == std::string::npos) + throw std::runtime_error("Incompatible filter file"); + } + + ifs.seekg(0, ifs.end); + int length = ifs.tellg(); + ifs.seekg(0, ifs.beg); + + std::vector buffer(length); + + ifs.read(buffer.data(), length); + ifs.close(); + + int ret = iio_device_attr_write_raw(phy, + "filter_fir_config", buffer.data(), length); + + return ret > 0; +} diff --git a/src/algorithms/signal_source/libs/ad9361_manager.h b/src/algorithms/signal_source/libs/ad9361_manager.h index 1d9bd42d0..10353ac64 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.h +++ b/src/algorithms/signal_source/libs/ad9361_manager.h @@ -132,4 +132,6 @@ bool ad9361_disable_lo_remote(const std::string &remote_host); bool ad9361_disable_lo_local(); +bool load_fir_filter(std::string &filter, struct iio_device *phy); + #endif // GNSS_SDR_AD9361_MANAGER_H_ From 43a8090dc66098bd5c53c881f6a6d4b781d9addc Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 9 Oct 2019 09:18:29 +0200 Subject: [PATCH 08/19] Add work in the AD9361 manager --- .../signal_source/libs/ad9361_manager.cc | 601 +++++++++++++++++- .../signal_source/libs/ad9361_manager.h | 55 +- 2 files changed, 616 insertions(+), 40 deletions(-) diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index 4a7611ef8..a57aadf27 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -38,6 +38,30 @@ #include #include +#define MIN_ADC_CLK 25000000UL // 25 MHz +#define MAX_ADC_CLK 640000000UL // 640 MHz +#define MIN_DATA_RATE MIN_ADC_CLK / 48 +#define MAX_DATA_RATE 61440000UL // Output of FIR (RX) +#define MAX_DAC_CLK (MAX_ADC_CLK / 2) +#define MIN_DAC_CLK 25000000UL // 25 MHz +#define MAX_RX_HB1 122880000UL +#define MAX_RX_HB2 245760000UL +#define MAX_RX_HB3 320000000UL +#define MAX_TX_HB1 122880000UL +#define MAX_TX_HB2 245760000UL +#define MAX_TX_HB3 320000000UL +#define MAX_FIR MAX_DATA_RATE * 2 +#define MAX_BBPLL_DIV 64 +#define MIN_BBPLL_FREQ 714928500UL // 715 MHz - 100ppm +#define MAX_BBPLL_FREQ 1430143000UL // 1430 MHz + 100ppm +#define check(val, min, max) ((val) <= (max) ? (val) >= (min) : false) + +const uint64_t TX_MAX_PATH_RATES[] = {MAX_DAC_CLK, MAX_TX_HB3, MAX_TX_HB2, MAX_TX_HB1, MAX_FIR}; +const uint64_t TX_MIN_PATH_RATES[] = {MIN_DAC_CLK, 0, 0, 0, 0}; +const uint64_t RX_MAX_PATH_RATES[] = {MAX_ADC_CLK, MAX_RX_HB3, MAX_RX_HB2, MAX_RX_HB1, MAX_FIR}; +const uint64_t RX_MIN_PATH_RATES[] = {MIN_ADC_CLK, 0, 0, 0, 0}; + +uint64_t max_rate_found; /* check return value of attr_write function */ void errchk(int v, const char *what) @@ -71,6 +95,508 @@ struct iio_device *get_ad9361_phy(struct iio_context *ctx) } +void set_max_taps(struct filter_design_parameters *fdpTX, + struct filter_design_parameters *fdpRX) +{ + // RX side + int N, M, K; + if (fdpRX->HB3 == 3) + N = 16 * floor(fdpRX->converter_rate / (fdpRX->Rdata)); + else + N = 16 * floor(fdpRX->converter_rate / (2 * fdpRX->Rdata)); + if (N > 128) + N = 128; + // TX side + if (fdpTX->FIR == 1) + M = 64; + else + M = 128; + K = 16 * floor(fdpTX->converter_rate * fdpTX->DAC_div / (2 * fdpTX->Rdata)); + if (K < M) + M = K; + + // Pick the smallest + if (M > N) + { + fdpTX->maxTaps = N; + fdpRX->maxTaps = N; + } + else + { + fdpTX->maxTaps = M; + fdpRX->maxTaps = M; + } +} + + +double calculate_rfbw(double pll_rate, double caldiv, bool TX, + double *rcaldiv) +{ + double rfbw, min_rfbw, max_rfbw, scale; + if (TX) + { + scale = 1.6; + min_rfbw = 1250000; + max_rfbw = 40000000; + } + else + { + scale = 1.4; + min_rfbw = 400000; + max_rfbw = 56000000; + } + rfbw = + (double)round((pll_rate / caldiv) * (2 / (scale * (2 * M_PI) / log(2)))); + + // If the RF bandwidth is outside the range of acceptable values we modify + // the divider value until it falls into an acceptable range. + while ((rfbw < min_rfbw) || (rfbw > max_rfbw)) + { + if (rfbw < min_rfbw) + caldiv = caldiv - 1; + else + caldiv = caldiv + 1; + + if ((caldiv < 1) || (caldiv > 511)) + { + fprintf(stderr, "Calibration divider out of bounds (1 - 511): %f\n", caldiv); + return -EINVAL; + } + rfbw = calculate_rfbw(pll_rate, caldiv, TX, rcaldiv); + } + *rcaldiv = caldiv; + return rfbw; +} + +void set_rates(uint64_t *rx_path_clks, + uint64_t *tx_path_clks, int DAC_div, uint64_t *rates, + int dec_table_index) +{ + int k; + + // Check if ADC will run faster in config + if (rates[1] > max_rate_found) + max_rate_found = rates[1]; + else + return; + + for (k = 0; k < 6; k++) + { + rx_path_clks[k] = rates[k]; + tx_path_clks[k] = rates[k]; + + if (k > 0) + { // Adjust HB's for DAC divider setting + if ((dec_table_index < 2) && (k < 4)) + tx_path_clks[k] = rates[k] / DAC_div; + else if ((dec_table_index < 4) && (k < 3)) + tx_path_clks[k] = rates[k] / DAC_div; + } + } +} + + +int check_dac_adc_config(uint64_t pll_bb, int PLL_mult, + int dec_table_index) +{ + // Need to determine if DAC divider is required and if ADC and DAC rates + // can be satisfied + uint64_t with_dd, without_dd; + bool a, b, c; + + with_dd = pll_bb / PLL_mult / 2; + without_dd = pll_bb / PLL_mult / 1; + + a = check(with_dd, MIN_DAC_CLK, MAX_DAC_CLK); + b = check(without_dd, MIN_ADC_CLK, MAX_ADC_CLK); + c = check(without_dd, MIN_DAC_CLK, MAX_DAC_CLK); + + if (c && b) + return 1; // Run without dac div + else if (a && b && (dec_table_index < 5)) + return 2; // Run with dac div + else + return -1; +} + + +bool check_rates(int FIR __attribute__((unused)), const int *HB_configs, uint64_t samp_rate, + uint64_t *rates) +{ + int j; + bool c = true; + + rates[5] = samp_rate; + for (j = 4; j > 0; j--) + { + rates[j] = rates[j + 1] * HB_configs[j - 1]; + if (j > 1) + { + c &= check(rates[j], TX_MIN_PATH_RATES[j - 1], TX_MAX_PATH_RATES[j - 1]); + c &= check(rates[j], RX_MIN_PATH_RATES[j - 1], RX_MAX_PATH_RATES[j - 1]); + } + } + return c; +} + + +int determine_pll_div(uint64_t *rates) +{ + // Determine necessary PLL multiplier + uint64_t tmp; + int PLL_mult = MAX_BBPLL_DIV; + while (PLL_mult > 1) + { + tmp = (uint64_t)rates[1] * PLL_mult; + if (check(tmp, MIN_BBPLL_FREQ, MAX_BBPLL_FREQ)) + { + rates[0] = (uint64_t)rates[1] * PLL_mult; + return PLL_mult; + } + PLL_mult >>= 1; + } + return -1; +} + + +int determine_path_rates_with_fir(uint64_t sample_rate, + uint64_t rate_gov, + uint64_t *rx_path_clks, + uint64_t *tx_path_clks, + int FIR) +{ + uint64_t rates[6]; + int PLL_mult, k; + + max_rate_found = 0UL; + + const int HB_configs[][4] = { + {3, 2, 2, FIR}, //12 + {2, 2, 2, FIR}, //8 + {3, 2, 1, FIR}, //6 + {2, 2, 1, FIR}, //4 + {2, 1, 1, FIR}, //2 + {3, 1, 1, FIR}, //3 + {1, 1, 1, FIR}, //1 + }; + + // RX Path: + // BBPLL -> /PLL_div -> /HB3 -> /HB2 -> /HB1 -> /FIR + // TX Path: + // BBPLL -> /(PLL_div*DAC_div) -> /HB3 -> /HB2 -> /HB1 -> /FIR + + // Cycle through possible decimations from highest to lowest + for (k = 0; k < 7; k++) + { + // HB3 cannot be 3 if rate_gov enabled + if ((rate_gov > 0) && HB_configs[k][0] == 3) + continue; + // Check if HB and FIR rates are valid + if (check_rates(FIR, HB_configs[k], sample_rate, rates)) + { + // Calculate PLL divider for configuration + PLL_mult = determine_pll_div(rates); + if (PLL_mult > 0) + { + // Determine DAC divider setting and check ADC/DAC settings + int dac_div = check_dac_adc_config(rates[0], PLL_mult, k); + // printf("dac_div: %d\n",dac_div); + if (dac_div > 0) + set_rates(rx_path_clks, tx_path_clks, dac_div, rates, k); + } + } + } + + if (max_rate_found == 0UL) + return -EINVAL; + else + return 0; +} + + +int ad9361_calculate_rf_clock_chain(uint64_t sample_rate, + uint64_t rate_gov, + uint64_t *rx_path_clks, + uint64_t *tx_path_clks) +{ + int ret, k; + int FIR[] = {4, 2, 1}; + + // Check desired rate within bounds + if (!check(sample_rate, MIN_DATA_RATE, MAX_DATA_RATE)) + return -EINVAL; + + // Rate selection will try to: + // 1. Utilize the maximum decimation in the FIR + // 2. Run the ADC/DAC as fast as possible + // 3. Use the most decimation possible starting with HB3(closest to ADC)->HB1 + + // Cycle through available FIR settings + for (k = 0; k < 3; k++) + { + ret = determine_path_rates_with_fir(sample_rate, rate_gov, rx_path_clks, + tx_path_clks, FIR[k]); + if (ret == 0) + break; + } + return ret; +} + + +int apply_custom_filter(struct iio_device *dev, unsigned dec_tx, + unsigned dec_rx, short *tapsTx, + short *tapsRx, unsigned taps, + uint64_t rate, + int gain_tx, int gain_rx, + uint64_t wnom_tx, uint64_t wnom_rx) +{ + struct iio_channel *chanTX, *chanRX; + long long current_rate; + int ret, i, enable, len = 0; + char *buf; + + chanTX = iio_device_find_channel(dev, "voltage0", true); + if (chanTX == NULL) + return -ENODEV; + + ret = iio_channel_attr_read_longlong(chanTX, "sampling_frequency", ¤t_rate); + if (ret < 0) + return ret; + + ret = ad9361_get_trx_fir_enable(dev, &enable); + if (ret < 0) + return ret; + + if (enable) + { + if (current_rate <= (25000000 / 12)) + iio_channel_attr_write_longlong(chanTX, "sampling_frequency", 3000000); + + ret = ad9361_set_trx_fir_enable(dev, false); + if (ret < 0) + return ret; + } + + buf = (char *)malloc(FIR_BUF_SIZE); + if (!buf) + return -ENOMEM; + + + len += snprintf(buf + len, FIR_BUF_SIZE - len, "RX 3 GAIN %d DEC %d\n", gain_rx, + dec_rx); + len += snprintf(buf + len, FIR_BUF_SIZE - len, "TX 3 GAIN %d INT %d\n", gain_tx, + dec_tx); + + for (i = 0; i < (int)taps; i++) + len += snprintf(buf + len, FIR_BUF_SIZE - len, "%d,%d\n", tapsRx[i], tapsTx[i]); + + len += snprintf(buf + len, FIR_BUF_SIZE - len, "\n"); + + ret = iio_device_attr_write_raw(dev, "filter_fir_config", buf, len); + free(buf); + + if (ret < 0) + return ret; + + if (rate <= (25000000 / 12)) + { + int dacrate, txrate, max; + char readbuf[100]; + ret = iio_device_attr_read(dev, "tx_path_rates", readbuf, sizeof(readbuf)); + if (ret < 0) + return ret; + ret = sscanf(readbuf, "BBPLL:%*d DAC:%d T2:%*d T1:%*d TF:%*d TXSAMP:%d", + &dacrate, &txrate); + if (ret != 2) + return -EFAULT; + if (txrate == 0) + return -EINVAL; + max = (dacrate / txrate) * 16; + if (max < taps) + iio_channel_attr_write_longlong(chanTX, "sampling_frequency", 3000000); + + + ret = ad9361_set_trx_fir_enable(dev, true); + if (ret < 0) + return ret; + ret = iio_channel_attr_write_longlong(chanTX, "sampling_frequency", rate); + if (ret < 0) + return ret; + } + else + { + ret = iio_channel_attr_write_longlong(chanTX, "sampling_frequency", rate); + if (ret < 0) + return ret; + ret = ad9361_set_trx_fir_enable(dev, true); + if (ret < 0) + return ret; + } + + chanRX = iio_device_find_channel(dev, "voltage0", false); + if (chanRX == NULL) + return -ENODEV; + ret = iio_channel_attr_write_longlong(chanTX, "rf_bandwidth", wnom_tx); + if (ret < 0) + return ret; + ret = iio_channel_attr_write_longlong(chanRX, "rf_bandwidth", wnom_rx); + if (ret < 0) + return ret; + + return 0; +} + + +int ad9361_set_bb_rate_custom_filter_auto(struct iio_device *dev, + uint64_t rate) +{ + struct filter_design_parameters fdpTX; + struct filter_design_parameters fdpRX; + short taps_tx[128]; + short taps_rx[128]; + int ret, num_taps_tx, num_taps_rx, gain_tx, gain_rx; + unsigned dec_tx, dec_rx, num_taps; + + ret = ad9361_calculate_rf_clock_chain_fdp(&fdpTX, &fdpRX, rate); + if (ret < 0) + return ret; + + ret = ad9361_generate_fir_taps(&fdpRX, taps_rx, &num_taps_rx, &gain_rx); + if (ret < 0) + return ret; + + ret = ad9361_generate_fir_taps(&fdpTX, taps_tx, &num_taps_tx, &gain_tx); + if (ret < 0) + return ret; + + dec_tx = (unsigned)fdpTX.FIR; + dec_rx = (unsigned)fdpRX.FIR; + num_taps = (unsigned)fdpTX.maxTaps; + ret = apply_custom_filter(dev, dec_tx, dec_rx, taps_tx, taps_rx, num_taps, + rate, gain_tx, gain_rx, fdpTX.wnom, fdpRX.wnom); + if (ret < 0) + return ret; + + return 0; +} + +int build_configuration(struct filter_design_parameters *fdpTX, + struct filter_design_parameters *fdpRX, + uint64_t sample_rate, + uint64_t Fpass, + uint64_t Fstop, + uint64_t wnomTX, + uint64_t wnomRX) +{ + double div, max; + uint64_t rx_path_clk[6]; + uint64_t tx_path_clk[6]; + uint64_t *path_clk; + struct filter_design_parameters *fdp; + int ret, k; + uint64_t rate_gov = 0; + + ret = ad9361_calculate_rf_clock_chain((uint64_t)sample_rate, + rate_gov, rx_path_clk, tx_path_clk); + if (ret < 0) + return -EINVAL; + + for (k = 0; k < 2; k++) + { + if (k > 0) + { + path_clk = tx_path_clk; + fdp = fdpTX; + fdp->RxTx = "Tx"; + fdp->DAC_div = (double)rx_path_clk[1] / tx_path_clk[1]; + } + else + { + path_clk = rx_path_clk; + fdp = fdpRX; + fdp->RxTx = "Rx"; + fdp->DAC_div = 1.0; + } + // Map rates and dividers + fdp->PLL_rate = (double)path_clk[0]; + fdp->converter_rate = (double)path_clk[1]; + fdp->PLL_mult = (double)path_clk[0] / path_clk[1]; + fdp->HB3 = (double)path_clk[1] / path_clk[2]; + fdp->HB2 = (double)path_clk[2] / path_clk[3]; + fdp->HB1 = (double)path_clk[3] / path_clk[4]; + fdp->FIR = (double)path_clk[4] / path_clk[5]; + + // Set default parameters + fdp->Rdata = (double)path_clk[5]; + fdp->Type = "Lowpass"; + fdp->int_FIR = 1; + fdp->Apass = 0.5; + fdp->Astop = 80; + fdp->phEQ = -1; + fdp->FIRdBmin = 0; + // Define filter design specifications + fdp->Fpass = (double)Fpass; + fdp->Fstop = (double)Fstop; + fdp->Fcenter = 0.0; + if (k > 0) + fdp->wnom = (double)wnomTX; + else + fdp->wnom = (double)wnomRX; + // Determine default analog bandwidth + div = ceil((fdp->PLL_rate / fdp->wnom) * (log(2) / (2 * M_PI))); + max = (div > 1) ? div : 1.0; + fdp->caldiv = (max > 511) ? 511.0 : max; + fdp->RFbw = calculate_rfbw(fdp->PLL_rate, fdp->caldiv, k > 0, &(fdp->caldiv)); + + if (fdp->RFbw < 0) + return -EINVAL; + } + set_max_taps(fdpTX, fdpRX); + + return 0; +} + + +int ad9361_set_bb_rate_custom_filter_manual(struct iio_device *dev, + uint64_t rate, uint64_t Fpass, + uint64_t Fstop, uint64_t wnom_tx, uint64_t wnom_rx) +{ + struct filter_design_parameters fdpTX; + struct filter_design_parameters fdpRX; + short taps_tx[128]; + short taps_rx[128]; + int ret, num_taps_tx, num_taps_rx, gain_tx, gain_rx; + unsigned dec_tx, dec_rx, num_taps; + + if (Fpass >= Fstop) + return -EINVAL; + + ret = build_configuration(&fdpTX, &fdpRX, rate, Fpass, Fstop, wnom_tx, + wnom_rx); + if (ret < 0) + return ret; + + ret = ad9361_generate_fir_taps(&fdpRX, taps_rx, &num_taps_rx, &gain_rx); + if (ret < 0) + return ret; + + ret = ad9361_generate_fir_taps(&fdpTX, taps_tx, &num_taps_tx, &gain_tx); + if (ret < 0) + return ret; + + dec_tx = (unsigned)fdpTX.FIR; + dec_rx = (unsigned)fdpRX.FIR; + num_taps = (unsigned)fdpTX.maxTaps; + + ret = apply_custom_filter(dev, dec_tx, dec_rx, taps_tx, taps_rx, num_taps, + rate, gain_tx, gain_rx, wnom_tx, wnom_rx); + if (ret < 0) + return ret; + + return 0; +} + + /* finds AD9361 streaming IIO devices */ bool get_ad9361_stream_dev(struct iio_context *ctx, enum iodev d, struct iio_device **dev) { @@ -195,17 +721,17 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, // 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.) + rxcfg.bw_hz = bandwidth_; + rxcfg.fs_hz = sample_rate_; + rxcfg.lo_hz = freq_; + rxcfg.rfport = rf_port_select_.c_str(); 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; + struct iio_channel *rx_chan1; + struct iio_channel *rx_chan2; ctx = iio_create_default_context(); if (!ctx) @@ -236,21 +762,21 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, } std::cout << "* Initializing AD9361 IIO streaming channels\n"; - if (!get_ad9361_stream_ch(ctx, RX, rx, 0, &rx0_i)) + if (!get_ad9361_stream_ch(ctx, RX, rx, 0, &rx_chan1)) { - std::cout << "RX chan i not found\n"; - throw std::runtime_error("RX chan i not found"); + std::cout << "RX channel 1 not found\n"; + throw std::runtime_error("RX channel 1 not found"); } - if (!get_ad9361_stream_ch(ctx, RX, rx, 1, &rx0_q)) + if (!get_ad9361_stream_ch(ctx, RX, rx, 1, &rx_chan2)) { - std::cout << "RX chan q not found\n"; - throw std::runtime_error("RX chan q not found"); + std::cout << "RX channel 2 not found\n"; + throw std::runtime_error("RX channel 2 not found"); } std::cout << "* Enabling IIO streaming channels\n"; - iio_channel_enable(rx0_i); - iio_channel_enable(rx0_q); + iio_channel_enable(rx_chan1); + iio_channel_enable(rx_chan2); struct iio_device *ad9361_phy; ad9361_phy = iio_context_find_device(ctx, "ad9361-phy"); @@ -334,8 +860,8 @@ bool config_ad9361_rx_remote(const std::string &remote_host, struct iio_context *ctx; // Streaming devices struct iio_device *rx; - struct iio_channel *rx0_i; - struct iio_channel *rx0_q; + struct iio_channel *rx_chan1; + struct iio_channel *rx_chan2; ctx = iio_create_network_context(remote_host.c_str()); if (!ctx) @@ -365,13 +891,13 @@ bool config_ad9361_rx_remote(const std::string &remote_host, int ret; std::cout << "* Initializing AD9361 IIO streaming channels\n"; - if (!get_ad9361_stream_ch(ctx, RX, rx, 0, &rx0_i)) + if (!get_ad9361_stream_ch(ctx, RX, rx, 0, &rx_chan1)) { 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)) + if (!get_ad9361_stream_ch(ctx, RX, rx, 1, &rx_chan2)) { std::cout << "RX chan q not found\n"; throw std::runtime_error("RX chan q not found"); @@ -400,20 +926,18 @@ bool config_ad9361_rx_remote(const std::string &remote_host, // set bw //params.push_back("in_voltage_rf_bandwidth=" + boost::to_string(bandwidth)); } - //wr_ch_str(rx0_i, "rf_port_select", rf_port_select_.c_str()); + //wr_ch_str(rx_chan1, "rf_port_select", rf_port_select_.c_str()); ret = iio_device_attr_write(ad9361_phy, "in_voltage0_rf_port_select", rf_port_select_.c_str()); if (ret) { throw std::runtime_error("Unable to set rf_port_select"); } - wr_ch_lli(rx0_i, "rf_bandwidth", bandwidth_); - - //if (!get_lo_chan(ctx, "RX", &chn)) - // { - // return false; - // } - //wr_ch_lli(chn, "frequency", freq_); - // in_voltage0_rf_port_select + wr_ch_lli(rx_chan1, "rf_bandwidth", bandwidth_); + if (!get_lo_chan(ctx, RX, &rx_chan1)) + { + return false; + } + wr_ch_lli(rx_chan1, "frequency", freq_); } else if (filter_source_ == "File") { @@ -433,13 +957,17 @@ bool config_ad9361_rx_remote(const std::string &remote_host, { throw std::runtime_error("Unable to set rf_port_select"); } - wr_ch_lli(rx0_i, "rf_bandwidth", bandwidth_); - wr_ch_lli(rx0_i, "frequency", freq_); + wr_ch_lli(rx_chan1, "rf_bandwidth", bandwidth_); + if (!get_lo_chan(ctx, RX, &rx_chan1)) + { + return false; + } + wr_ch_lli(rx_chan1, "frequency", freq_); } else if (filter_source_ == "Design") { ret = ad9361_set_bb_rate_custom_filter_manual( - ad9361_phy, sample_rate_, Fpass_, Fstop_, bandwidth_, bandwidth_); + ad9361_phy, sample_rate_, static_cast(Fpass_), static_cast(Fstop_), bandwidth_, bandwidth_); if (ret) { throw std::runtime_error("Unable to set BB rate"); @@ -449,8 +977,12 @@ bool config_ad9361_rx_remote(const std::string &remote_host, { throw std::runtime_error("Unable to set rf_port_select"); } - wr_ch_lli(rx0_i, "rf_bandwidth", bandwidth_); - wr_ch_lli(rx0_i, "frequency", freq_); + wr_ch_lli(rx_chan1, "rf_bandwidth", bandwidth_); + if (!get_lo_chan(ctx, RX, &rx_chan1)) + { + return false; + } + wr_ch_lli(rx_chan1, "frequency", freq_); } else { @@ -468,8 +1000,8 @@ bool config_ad9361_rx_remote(const std::string &remote_host, } std::cout << "* Enabling IIO streaming channels\n"; - iio_channel_enable(rx0_i); - iio_channel_enable(rx0_q); + iio_channel_enable(rx_chan1); + iio_channel_enable(rx_chan2); ret = iio_device_attr_write(ad9361_phy, "trx_rate_governor", "nominal"); if (ret < 0) @@ -528,7 +1060,6 @@ bool config_ad9361_rx_remote(const std::string &remote_host, } } - std::cout << "End of AD9361 RX configuration.\n"; iio_context_destroy(ctx); diff --git a/src/algorithms/signal_source/libs/ad9361_manager.h b/src/algorithms/signal_source/libs/ad9361_manager.h index 10353ac64..e94bfd55b 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.h +++ b/src/algorithms/signal_source/libs/ad9361_manager.h @@ -37,6 +37,7 @@ #include #include +#define FIR_BUF_SIZE 8192 /* RX is input, TX is output */ enum iodev @@ -48,7 +49,7 @@ enum iodev /* common RX and TX streaming params */ struct stream_cfg { - int64_t bw_hz; // Analog banwidth in Hz + int64_t bw_hz; // Analog bandwidth in Hz int64_t fs_hz; // Baseband sample rate in Hz int64_t lo_hz; // Local oscillator frequency in Hz const char *rfport; // Port name @@ -64,9 +65,6 @@ void wr_ch_lli(struct iio_channel *chn, const char *what, int64_t 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); @@ -127,11 +125,58 @@ bool config_ad9361_lo_remote(const std::string &remote_host, double scale_dds_dbfs_, double phase_dds_deg_); - bool ad9361_disable_lo_remote(const std::string &remote_host); bool ad9361_disable_lo_local(); bool load_fir_filter(std::string &filter, struct iio_device *phy); +int ad9361_set_bb_rate_custom_filter_manual(struct iio_device *dev, + uint64_t rate, uint64_t Fpass, + uint64_t Fstop, uint64_t wnom_tx, uint64_t wnom_rx); + +int ad9361_set_bb_rate_custom_filter_auto(struct iio_device *dev, + uint64_t rate); + +int apply_custom_filter(struct iio_device *dev, unsigned dec_tx, + unsigned dec_rx, short *tapsTx, + short *tapsRx, unsigned taps, + uint64_t rate, + int gain_tx, int gain_rx, + uint64_t wnom_tx, uint64_t wnom_rx); + +int ad9361_calculate_rf_clock_chain(uint64_t sample_rate, + uint64_t rate_gov, + uint64_t *rx_path_clks, + uint64_t *tx_path_clks); + +int determine_path_rates_with_fir(uint64_t sample_rate, + uint64_t rate_gov, + uint64_t *rx_path_clks, + uint64_t *tx_path_clks, + uint64_t tmp, + int FIR); + +bool check_rates(int FIR, const int *HB_configs, uint64_t samp_rate, + uint64_t *rates); + +int determine_pll_div(uint64_t *rates); + +int check_dac_adc_config(uint64_t pll_bb, int PLL_mult, + int dec_table_index); + +double calculate_rfbw(double pll_rate, double caldiv, bool TX, + double *rcaldiv); + +int build_configuration(struct filter_design_parameters *fdpTX, + struct filter_design_parameters *fdpRX, + uint64_t sample_rate, + uint64_t Fpass, + uint64_t Fstop, + uint64_t wnomTX, + uint64_t wnomRX); + +void set_max_taps(struct filter_design_parameters *fdpTX, + struct filter_design_parameters *fdpRX); + #endif // GNSS_SDR_AD9361_MANAGER_H_ From c081c2ea5794f0d3ee93e04f09df6669c850f3ac Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 9 Oct 2019 19:05:31 +0200 Subject: [PATCH 09/19] Add work on FIR configuration --- CMakeLists.txt | 1 + .../signal_source/libs/ad9361_manager.cc | 537 +----------------- .../signal_source/libs/ad9361_manager.h | 49 -- 3 files changed, 6 insertions(+), 581 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a93d2cf3..d142a7b92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2293,6 +2293,7 @@ set_package_properties(LIBAD9361 PROPERTIES ) if(NOT LIBAD9361_FOUND) set(GRIIO_FOUND FALSE) + set(ENABLE_AD9361 OFF) endif() if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) if(NOT GRIIO_FOUND) diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index a57aadf27..c06943571 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -38,31 +38,6 @@ #include #include -#define MIN_ADC_CLK 25000000UL // 25 MHz -#define MAX_ADC_CLK 640000000UL // 640 MHz -#define MIN_DATA_RATE MIN_ADC_CLK / 48 -#define MAX_DATA_RATE 61440000UL // Output of FIR (RX) -#define MAX_DAC_CLK (MAX_ADC_CLK / 2) -#define MIN_DAC_CLK 25000000UL // 25 MHz -#define MAX_RX_HB1 122880000UL -#define MAX_RX_HB2 245760000UL -#define MAX_RX_HB3 320000000UL -#define MAX_TX_HB1 122880000UL -#define MAX_TX_HB2 245760000UL -#define MAX_TX_HB3 320000000UL -#define MAX_FIR MAX_DATA_RATE * 2 -#define MAX_BBPLL_DIV 64 -#define MIN_BBPLL_FREQ 714928500UL // 715 MHz - 100ppm -#define MAX_BBPLL_FREQ 1430143000UL // 1430 MHz + 100ppm -#define check(val, min, max) ((val) <= (max) ? (val) >= (min) : false) - -const uint64_t TX_MAX_PATH_RATES[] = {MAX_DAC_CLK, MAX_TX_HB3, MAX_TX_HB2, MAX_TX_HB1, MAX_FIR}; -const uint64_t TX_MIN_PATH_RATES[] = {MIN_DAC_CLK, 0, 0, 0, 0}; -const uint64_t RX_MAX_PATH_RATES[] = {MAX_ADC_CLK, MAX_RX_HB3, MAX_RX_HB2, MAX_RX_HB1, MAX_FIR}; -const uint64_t RX_MIN_PATH_RATES[] = {MIN_ADC_CLK, 0, 0, 0, 0}; - -uint64_t max_rate_found; - /* check return value of attr_write function */ void errchk(int v, const char *what) { @@ -95,508 +70,6 @@ struct iio_device *get_ad9361_phy(struct iio_context *ctx) } -void set_max_taps(struct filter_design_parameters *fdpTX, - struct filter_design_parameters *fdpRX) -{ - // RX side - int N, M, K; - if (fdpRX->HB3 == 3) - N = 16 * floor(fdpRX->converter_rate / (fdpRX->Rdata)); - else - N = 16 * floor(fdpRX->converter_rate / (2 * fdpRX->Rdata)); - if (N > 128) - N = 128; - // TX side - if (fdpTX->FIR == 1) - M = 64; - else - M = 128; - K = 16 * floor(fdpTX->converter_rate * fdpTX->DAC_div / (2 * fdpTX->Rdata)); - if (K < M) - M = K; - - // Pick the smallest - if (M > N) - { - fdpTX->maxTaps = N; - fdpRX->maxTaps = N; - } - else - { - fdpTX->maxTaps = M; - fdpRX->maxTaps = M; - } -} - - -double calculate_rfbw(double pll_rate, double caldiv, bool TX, - double *rcaldiv) -{ - double rfbw, min_rfbw, max_rfbw, scale; - if (TX) - { - scale = 1.6; - min_rfbw = 1250000; - max_rfbw = 40000000; - } - else - { - scale = 1.4; - min_rfbw = 400000; - max_rfbw = 56000000; - } - rfbw = - (double)round((pll_rate / caldiv) * (2 / (scale * (2 * M_PI) / log(2)))); - - // If the RF bandwidth is outside the range of acceptable values we modify - // the divider value until it falls into an acceptable range. - while ((rfbw < min_rfbw) || (rfbw > max_rfbw)) - { - if (rfbw < min_rfbw) - caldiv = caldiv - 1; - else - caldiv = caldiv + 1; - - if ((caldiv < 1) || (caldiv > 511)) - { - fprintf(stderr, "Calibration divider out of bounds (1 - 511): %f\n", caldiv); - return -EINVAL; - } - rfbw = calculate_rfbw(pll_rate, caldiv, TX, rcaldiv); - } - *rcaldiv = caldiv; - return rfbw; -} - -void set_rates(uint64_t *rx_path_clks, - uint64_t *tx_path_clks, int DAC_div, uint64_t *rates, - int dec_table_index) -{ - int k; - - // Check if ADC will run faster in config - if (rates[1] > max_rate_found) - max_rate_found = rates[1]; - else - return; - - for (k = 0; k < 6; k++) - { - rx_path_clks[k] = rates[k]; - tx_path_clks[k] = rates[k]; - - if (k > 0) - { // Adjust HB's for DAC divider setting - if ((dec_table_index < 2) && (k < 4)) - tx_path_clks[k] = rates[k] / DAC_div; - else if ((dec_table_index < 4) && (k < 3)) - tx_path_clks[k] = rates[k] / DAC_div; - } - } -} - - -int check_dac_adc_config(uint64_t pll_bb, int PLL_mult, - int dec_table_index) -{ - // Need to determine if DAC divider is required and if ADC and DAC rates - // can be satisfied - uint64_t with_dd, without_dd; - bool a, b, c; - - with_dd = pll_bb / PLL_mult / 2; - without_dd = pll_bb / PLL_mult / 1; - - a = check(with_dd, MIN_DAC_CLK, MAX_DAC_CLK); - b = check(without_dd, MIN_ADC_CLK, MAX_ADC_CLK); - c = check(without_dd, MIN_DAC_CLK, MAX_DAC_CLK); - - if (c && b) - return 1; // Run without dac div - else if (a && b && (dec_table_index < 5)) - return 2; // Run with dac div - else - return -1; -} - - -bool check_rates(int FIR __attribute__((unused)), const int *HB_configs, uint64_t samp_rate, - uint64_t *rates) -{ - int j; - bool c = true; - - rates[5] = samp_rate; - for (j = 4; j > 0; j--) - { - rates[j] = rates[j + 1] * HB_configs[j - 1]; - if (j > 1) - { - c &= check(rates[j], TX_MIN_PATH_RATES[j - 1], TX_MAX_PATH_RATES[j - 1]); - c &= check(rates[j], RX_MIN_PATH_RATES[j - 1], RX_MAX_PATH_RATES[j - 1]); - } - } - return c; -} - - -int determine_pll_div(uint64_t *rates) -{ - // Determine necessary PLL multiplier - uint64_t tmp; - int PLL_mult = MAX_BBPLL_DIV; - while (PLL_mult > 1) - { - tmp = (uint64_t)rates[1] * PLL_mult; - if (check(tmp, MIN_BBPLL_FREQ, MAX_BBPLL_FREQ)) - { - rates[0] = (uint64_t)rates[1] * PLL_mult; - return PLL_mult; - } - PLL_mult >>= 1; - } - return -1; -} - - -int determine_path_rates_with_fir(uint64_t sample_rate, - uint64_t rate_gov, - uint64_t *rx_path_clks, - uint64_t *tx_path_clks, - int FIR) -{ - uint64_t rates[6]; - int PLL_mult, k; - - max_rate_found = 0UL; - - const int HB_configs[][4] = { - {3, 2, 2, FIR}, //12 - {2, 2, 2, FIR}, //8 - {3, 2, 1, FIR}, //6 - {2, 2, 1, FIR}, //4 - {2, 1, 1, FIR}, //2 - {3, 1, 1, FIR}, //3 - {1, 1, 1, FIR}, //1 - }; - - // RX Path: - // BBPLL -> /PLL_div -> /HB3 -> /HB2 -> /HB1 -> /FIR - // TX Path: - // BBPLL -> /(PLL_div*DAC_div) -> /HB3 -> /HB2 -> /HB1 -> /FIR - - // Cycle through possible decimations from highest to lowest - for (k = 0; k < 7; k++) - { - // HB3 cannot be 3 if rate_gov enabled - if ((rate_gov > 0) && HB_configs[k][0] == 3) - continue; - // Check if HB and FIR rates are valid - if (check_rates(FIR, HB_configs[k], sample_rate, rates)) - { - // Calculate PLL divider for configuration - PLL_mult = determine_pll_div(rates); - if (PLL_mult > 0) - { - // Determine DAC divider setting and check ADC/DAC settings - int dac_div = check_dac_adc_config(rates[0], PLL_mult, k); - // printf("dac_div: %d\n",dac_div); - if (dac_div > 0) - set_rates(rx_path_clks, tx_path_clks, dac_div, rates, k); - } - } - } - - if (max_rate_found == 0UL) - return -EINVAL; - else - return 0; -} - - -int ad9361_calculate_rf_clock_chain(uint64_t sample_rate, - uint64_t rate_gov, - uint64_t *rx_path_clks, - uint64_t *tx_path_clks) -{ - int ret, k; - int FIR[] = {4, 2, 1}; - - // Check desired rate within bounds - if (!check(sample_rate, MIN_DATA_RATE, MAX_DATA_RATE)) - return -EINVAL; - - // Rate selection will try to: - // 1. Utilize the maximum decimation in the FIR - // 2. Run the ADC/DAC as fast as possible - // 3. Use the most decimation possible starting with HB3(closest to ADC)->HB1 - - // Cycle through available FIR settings - for (k = 0; k < 3; k++) - { - ret = determine_path_rates_with_fir(sample_rate, rate_gov, rx_path_clks, - tx_path_clks, FIR[k]); - if (ret == 0) - break; - } - return ret; -} - - -int apply_custom_filter(struct iio_device *dev, unsigned dec_tx, - unsigned dec_rx, short *tapsTx, - short *tapsRx, unsigned taps, - uint64_t rate, - int gain_tx, int gain_rx, - uint64_t wnom_tx, uint64_t wnom_rx) -{ - struct iio_channel *chanTX, *chanRX; - long long current_rate; - int ret, i, enable, len = 0; - char *buf; - - chanTX = iio_device_find_channel(dev, "voltage0", true); - if (chanTX == NULL) - return -ENODEV; - - ret = iio_channel_attr_read_longlong(chanTX, "sampling_frequency", ¤t_rate); - if (ret < 0) - return ret; - - ret = ad9361_get_trx_fir_enable(dev, &enable); - if (ret < 0) - return ret; - - if (enable) - { - if (current_rate <= (25000000 / 12)) - iio_channel_attr_write_longlong(chanTX, "sampling_frequency", 3000000); - - ret = ad9361_set_trx_fir_enable(dev, false); - if (ret < 0) - return ret; - } - - buf = (char *)malloc(FIR_BUF_SIZE); - if (!buf) - return -ENOMEM; - - - len += snprintf(buf + len, FIR_BUF_SIZE - len, "RX 3 GAIN %d DEC %d\n", gain_rx, - dec_rx); - len += snprintf(buf + len, FIR_BUF_SIZE - len, "TX 3 GAIN %d INT %d\n", gain_tx, - dec_tx); - - for (i = 0; i < (int)taps; i++) - len += snprintf(buf + len, FIR_BUF_SIZE - len, "%d,%d\n", tapsRx[i], tapsTx[i]); - - len += snprintf(buf + len, FIR_BUF_SIZE - len, "\n"); - - ret = iio_device_attr_write_raw(dev, "filter_fir_config", buf, len); - free(buf); - - if (ret < 0) - return ret; - - if (rate <= (25000000 / 12)) - { - int dacrate, txrate, max; - char readbuf[100]; - ret = iio_device_attr_read(dev, "tx_path_rates", readbuf, sizeof(readbuf)); - if (ret < 0) - return ret; - ret = sscanf(readbuf, "BBPLL:%*d DAC:%d T2:%*d T1:%*d TF:%*d TXSAMP:%d", - &dacrate, &txrate); - if (ret != 2) - return -EFAULT; - if (txrate == 0) - return -EINVAL; - max = (dacrate / txrate) * 16; - if (max < taps) - iio_channel_attr_write_longlong(chanTX, "sampling_frequency", 3000000); - - - ret = ad9361_set_trx_fir_enable(dev, true); - if (ret < 0) - return ret; - ret = iio_channel_attr_write_longlong(chanTX, "sampling_frequency", rate); - if (ret < 0) - return ret; - } - else - { - ret = iio_channel_attr_write_longlong(chanTX, "sampling_frequency", rate); - if (ret < 0) - return ret; - ret = ad9361_set_trx_fir_enable(dev, true); - if (ret < 0) - return ret; - } - - chanRX = iio_device_find_channel(dev, "voltage0", false); - if (chanRX == NULL) - return -ENODEV; - ret = iio_channel_attr_write_longlong(chanTX, "rf_bandwidth", wnom_tx); - if (ret < 0) - return ret; - ret = iio_channel_attr_write_longlong(chanRX, "rf_bandwidth", wnom_rx); - if (ret < 0) - return ret; - - return 0; -} - - -int ad9361_set_bb_rate_custom_filter_auto(struct iio_device *dev, - uint64_t rate) -{ - struct filter_design_parameters fdpTX; - struct filter_design_parameters fdpRX; - short taps_tx[128]; - short taps_rx[128]; - int ret, num_taps_tx, num_taps_rx, gain_tx, gain_rx; - unsigned dec_tx, dec_rx, num_taps; - - ret = ad9361_calculate_rf_clock_chain_fdp(&fdpTX, &fdpRX, rate); - if (ret < 0) - return ret; - - ret = ad9361_generate_fir_taps(&fdpRX, taps_rx, &num_taps_rx, &gain_rx); - if (ret < 0) - return ret; - - ret = ad9361_generate_fir_taps(&fdpTX, taps_tx, &num_taps_tx, &gain_tx); - if (ret < 0) - return ret; - - dec_tx = (unsigned)fdpTX.FIR; - dec_rx = (unsigned)fdpRX.FIR; - num_taps = (unsigned)fdpTX.maxTaps; - ret = apply_custom_filter(dev, dec_tx, dec_rx, taps_tx, taps_rx, num_taps, - rate, gain_tx, gain_rx, fdpTX.wnom, fdpRX.wnom); - if (ret < 0) - return ret; - - return 0; -} - -int build_configuration(struct filter_design_parameters *fdpTX, - struct filter_design_parameters *fdpRX, - uint64_t sample_rate, - uint64_t Fpass, - uint64_t Fstop, - uint64_t wnomTX, - uint64_t wnomRX) -{ - double div, max; - uint64_t rx_path_clk[6]; - uint64_t tx_path_clk[6]; - uint64_t *path_clk; - struct filter_design_parameters *fdp; - int ret, k; - uint64_t rate_gov = 0; - - ret = ad9361_calculate_rf_clock_chain((uint64_t)sample_rate, - rate_gov, rx_path_clk, tx_path_clk); - if (ret < 0) - return -EINVAL; - - for (k = 0; k < 2; k++) - { - if (k > 0) - { - path_clk = tx_path_clk; - fdp = fdpTX; - fdp->RxTx = "Tx"; - fdp->DAC_div = (double)rx_path_clk[1] / tx_path_clk[1]; - } - else - { - path_clk = rx_path_clk; - fdp = fdpRX; - fdp->RxTx = "Rx"; - fdp->DAC_div = 1.0; - } - // Map rates and dividers - fdp->PLL_rate = (double)path_clk[0]; - fdp->converter_rate = (double)path_clk[1]; - fdp->PLL_mult = (double)path_clk[0] / path_clk[1]; - fdp->HB3 = (double)path_clk[1] / path_clk[2]; - fdp->HB2 = (double)path_clk[2] / path_clk[3]; - fdp->HB1 = (double)path_clk[3] / path_clk[4]; - fdp->FIR = (double)path_clk[4] / path_clk[5]; - - // Set default parameters - fdp->Rdata = (double)path_clk[5]; - fdp->Type = "Lowpass"; - fdp->int_FIR = 1; - fdp->Apass = 0.5; - fdp->Astop = 80; - fdp->phEQ = -1; - fdp->FIRdBmin = 0; - // Define filter design specifications - fdp->Fpass = (double)Fpass; - fdp->Fstop = (double)Fstop; - fdp->Fcenter = 0.0; - if (k > 0) - fdp->wnom = (double)wnomTX; - else - fdp->wnom = (double)wnomRX; - // Determine default analog bandwidth - div = ceil((fdp->PLL_rate / fdp->wnom) * (log(2) / (2 * M_PI))); - max = (div > 1) ? div : 1.0; - fdp->caldiv = (max > 511) ? 511.0 : max; - fdp->RFbw = calculate_rfbw(fdp->PLL_rate, fdp->caldiv, k > 0, &(fdp->caldiv)); - - if (fdp->RFbw < 0) - return -EINVAL; - } - set_max_taps(fdpTX, fdpRX); - - return 0; -} - - -int ad9361_set_bb_rate_custom_filter_manual(struct iio_device *dev, - uint64_t rate, uint64_t Fpass, - uint64_t Fstop, uint64_t wnom_tx, uint64_t wnom_rx) -{ - struct filter_design_parameters fdpTX; - struct filter_design_parameters fdpRX; - short taps_tx[128]; - short taps_rx[128]; - int ret, num_taps_tx, num_taps_rx, gain_tx, gain_rx; - unsigned dec_tx, dec_rx, num_taps; - - if (Fpass >= Fstop) - return -EINVAL; - - ret = build_configuration(&fdpTX, &fdpRX, rate, Fpass, Fstop, wnom_tx, - wnom_rx); - if (ret < 0) - return ret; - - ret = ad9361_generate_fir_taps(&fdpRX, taps_rx, &num_taps_rx, &gain_rx); - if (ret < 0) - return ret; - - ret = ad9361_generate_fir_taps(&fdpTX, taps_tx, &num_taps_tx, &gain_tx); - if (ret < 0) - return ret; - - dec_tx = (unsigned)fdpTX.FIR; - dec_rx = (unsigned)fdpRX.FIR; - num_taps = (unsigned)fdpTX.maxTaps; - - ret = apply_custom_filter(dev, dec_tx, dec_rx, taps_tx, taps_rx, num_taps, - rate, gain_tx, gain_rx, wnom_tx, wnom_rx); - if (ret < 0) - return ret; - - return 0; -} - - /* finds AD9361 streaming IIO devices */ bool get_ad9361_stream_dev(struct iio_context *ctx, enum iodev d, struct iio_device **dev) { @@ -893,14 +366,14 @@ bool config_ad9361_rx_remote(const std::string &remote_host, std::cout << "* Initializing AD9361 IIO streaming channels\n"; if (!get_ad9361_stream_ch(ctx, RX, rx, 0, &rx_chan1)) { - std::cout << "RX chan i not found\n"; - throw std::runtime_error("RX chan i not found"); + std::cout << "RX channel 1 not found\n"; + throw std::runtime_error("RX channel 1 not found"); } if (!get_ad9361_stream_ch(ctx, RX, rx, 1, &rx_chan2)) { - std::cout << "RX chan q not found\n"; - throw std::runtime_error("RX chan q not found"); + std::cout << "RX channel 2 not found\n"; + throw std::runtime_error("RX channel 2 not found"); } if (filter_source_ == "Off") @@ -1448,7 +921,7 @@ bool load_fir_filter( return false; } - /* Here, we verify that the filter file contains data for both RX+TX. */ + // Here, we verify that the filter file contains data for both RX+TX. { char buf[256]; do diff --git a/src/algorithms/signal_source/libs/ad9361_manager.h b/src/algorithms/signal_source/libs/ad9361_manager.h index e94bfd55b..7216ae4f8 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.h +++ b/src/algorithms/signal_source/libs/ad9361_manager.h @@ -55,7 +55,6 @@ struct stream_cfg const char *rfport; // Port name }; - /* check return value of attr_write function */ void errchk(int v, const char *what); @@ -131,52 +130,4 @@ bool ad9361_disable_lo_local(); bool load_fir_filter(std::string &filter, struct iio_device *phy); -int ad9361_set_bb_rate_custom_filter_manual(struct iio_device *dev, - uint64_t rate, uint64_t Fpass, - uint64_t Fstop, uint64_t wnom_tx, uint64_t wnom_rx); - -int ad9361_set_bb_rate_custom_filter_auto(struct iio_device *dev, - uint64_t rate); - -int apply_custom_filter(struct iio_device *dev, unsigned dec_tx, - unsigned dec_rx, short *tapsTx, - short *tapsRx, unsigned taps, - uint64_t rate, - int gain_tx, int gain_rx, - uint64_t wnom_tx, uint64_t wnom_rx); - -int ad9361_calculate_rf_clock_chain(uint64_t sample_rate, - uint64_t rate_gov, - uint64_t *rx_path_clks, - uint64_t *tx_path_clks); - -int determine_path_rates_with_fir(uint64_t sample_rate, - uint64_t rate_gov, - uint64_t *rx_path_clks, - uint64_t *tx_path_clks, - uint64_t tmp, - int FIR); - -bool check_rates(int FIR, const int *HB_configs, uint64_t samp_rate, - uint64_t *rates); - -int determine_pll_div(uint64_t *rates); - -int check_dac_adc_config(uint64_t pll_bb, int PLL_mult, - int dec_table_index); - -double calculate_rfbw(double pll_rate, double caldiv, bool TX, - double *rcaldiv); - -int build_configuration(struct filter_design_parameters *fdpTX, - struct filter_design_parameters *fdpRX, - uint64_t sample_rate, - uint64_t Fpass, - uint64_t Fstop, - uint64_t wnomTX, - uint64_t wnomRX); - -void set_max_taps(struct filter_design_parameters *fdpTX, - struct filter_design_parameters *fdpRX); - #endif // GNSS_SDR_AD9361_MANAGER_H_ From e4a39188f5bfb4f60069940281bf586a21262867 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 9 Oct 2019 20:50:06 +0200 Subject: [PATCH 10/19] Implement FIR filter configuration --- CMakeLists.txt | 2 +- cmake/Modules/FindLIBAD9361.cmake | 6 +- .../adapters/ad9361_fpga_signal_source.cc | 33 ++++- .../adapters/ad9361_fpga_signal_source.h | 4 + .../adapters/fmcomms2_signal_source.cc | 2 +- .../adapters/plutosdr_signal_source.cc | 2 +- .../signal_source/libs/ad9361_manager.cc | 134 ++++++++++++++---- .../signal_source/libs/ad9361_manager.h | 6 +- 8 files changed, 155 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d142a7b92..1442b0692 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2577,7 +2577,7 @@ add_feature_info(ENABLE_UHD ENABLE_UHD "Enables UHD_Signal_Source for using RF f 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_FMCOMMS2 ENABLE_FMCOMMS2 "Enables Fmcomms2_Signal_Source for FMCOMMS2/3/4 devices. Requires gr-iio.") 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.") +add_feature_info(ENABLE_AD9361 ENABLE_AD9361 "Enables Ad9361_Fpga_Signal_Source for devices with the AD9361 chipset. Requires libiio and libad9361.") 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_GN3S ENABLE_GN3S "Enables Gn3s_Signal_Source for using the GN3S v2 dongle. Requires gr-gn3s.") diff --git a/cmake/Modules/FindLIBAD9361.cmake b/cmake/Modules/FindLIBAD9361.cmake index a37671184..3daf9c8b0 100644 --- a/cmake/Modules/FindLIBAD9361.cmake +++ b/cmake/Modules/FindLIBAD9361.cmake @@ -74,7 +74,7 @@ find_library( /usr/local/lib /usr/local/lib64 /opt/local/lib - /Library/Frameworks/iio.framework/ + /Library/Frameworks/ad9361.framework ${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_INSTALL_PREFIX}/lib64 ${LIBAD9361_ROOT}/lib @@ -99,11 +99,11 @@ endif() if(LIBAD9361_FOUND AND LIBAD9361_VERSION) set_package_properties(LIBAD9361 PROPERTIES - DESCRIPTION "A library for interfacing with AD936X transceivers (found: v${LIBAD9361_VERSION})" + DESCRIPTION "A library for interfacing with AD936X RF transceivers (found: v${LIBAD9361_VERSION})" ) else() set_package_properties(LIBAD9361 PROPERTIES - DESCRIPTION "A library for interfacing with AD936X transceivers" + DESCRIPTION "A library for interfacing with AD936X RF transceivers" ) endif() diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc index 353ed1dc0..676956d33 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc @@ -279,7 +279,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura const std::string &role, unsigned int in_stream, unsigned int out_stream, std::shared_ptr> queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream), queue_(std::move(queue)) { - std::string default_gain_mode("slow attack"); + std::string default_gain_mode("slow_attack"); double default_tx_attenuation_db = -10.0; double default_manual_gain_rx1 = 64.0; double default_manual_gain_rx2 = 64.0; @@ -297,8 +297,18 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura rf_gain_rx2_ = configuration->property(role + ".gain_rx2", default_manual_gain_rx2); rf_port_select_ = configuration->property(role + ".rf_port_select", default_rf_port_select); filter_file_ = configuration->property(role + ".filter_file", std::string("")); + filter_filename_ = configuration->property(role + ".filter_filename", filter_file_); filter_auto_ = configuration->property(role + ".filter_auto", false); - + if (filter_auto_) + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Auto")); + } + else + { + filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); + } + Fpass_ = configuration->property(role + ".Fpass", 0.0); + Fstop_ = configuration->property(role + ".Fstop", 0.0); enable_dds_lo_ = configuration->property(role + ".enable_dds_lo", false); freq_dds_tx_hz_ = configuration->property(role + ".freq_dds_tx_hz", 1000); freq_rf_tx_hz_ = configuration->property(role + ".freq_rf_tx_hz", GPS_L1_FREQ_HZ - GPS_L2_FREQ_HZ - freq_dds_tx_hz_); @@ -410,6 +420,19 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura } } + if ((filter_source_ != "Off") and (filter_source_ != "Auto") and (filter_source_ != "File") and (filter_source_ != "Design")) + { + std::cout << "Configuration parameter filter_source should take one of these values:" << std::endl; + std::cout << " Off: Disable filter" << std::endl; + std::cout << " Auto: Use auto-generated filters" << std::endl; + std::cout << " File: User-provided filter in filter_filename parameter" << std::endl; + std::cout << " Design: Create filter from Fpass, Fstop, sampling_frequency and bandwidth parameters" << std::endl; + std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values" << std::endl; + std::cout << " This parameter has been set to its default value filter_source=Off" << std::endl; + filter_source_ = std::string("Off"); + LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off"; + } + if (bandwidth_ < 200000 or bandwidth_ > 56000000) { std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz" << std::endl; @@ -432,7 +455,11 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura rf_gain_rx2_, quadrature_, rf_dc_, - bb_dc_); + bb_dc_, + filter_source_, + filter_filename_, + Fpass_, + Fstop_); } catch (const std::runtime_error &e) { diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h index ca41a0fe8..3f4391d1d 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h @@ -93,6 +93,10 @@ private: std::string rf_port_select_; std::string filter_file_; bool filter_auto_; + std::string filter_source_; + std::string filter_filename_; + float Fpass_; + float Fstop_; // DDS configuration for LO generation for external mixer bool enable_dds_lo_; diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index 84b73a203..1d7a3f579 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -48,7 +48,7 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration { std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/signal_source.dat"; - std::string default_gain_mode("slow attack"); + std::string default_gain_mode("slow_attack"); double default_tx_attenuation_db = -10.0; uri_ = configuration->property(role + ".device_address", std::string("192.168.2.1")); freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ); diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc index d6ed8cf6e..6d30aac99 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc @@ -43,7 +43,7 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration { std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/signal_source.dat"; - std::string default_gain_mode("slow attack"); + std::string default_gain_mode("slow_attack"); uri_ = configuration->property(role + ".device_address", std::string("192.168.2.1")); freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ); sample_rate_ = configuration->property(role + ".sampling_frequency", 3000000); diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index c06943571..9be96a771 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -188,23 +188,21 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, double rf_gain_rx2_, bool quadrature_, bool rfdc_, - bool bbdc_) + bool bbdc_, + std::string filter_source_, + std::string filter_filename_, + float Fpass_, + float Fstop_) { // RX stream config - // Stream configurations - struct stream_cfg rxcfg; - rxcfg.bw_hz = bandwidth_; - rxcfg.fs_hz = sample_rate_; - rxcfg.lo_hz = freq_; - rxcfg.rfport = rf_port_select_.c_str(); - std::cout << "AD9361 Acquiring IIO LOCAL context\n"; struct iio_context *ctx; // Streaming devices struct iio_device *rx; struct iio_channel *rx_chan1; struct iio_channel *rx_chan2; + int ret; ctx = iio_create_default_context(); if (!ctx) @@ -219,21 +217,16 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, throw std::runtime_error("AD9361 IIO No devices"); } - std::cout << "* Acquiring AD9361 streaming devices\n"; + struct iio_device *ad9361_phy; + ad9361_phy = iio_context_find_device(ctx, "ad9361-phy"); + 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, &rx_chan1)) { @@ -247,13 +240,106 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, throw std::runtime_error("RX channel 2 not found"); } + if (filter_source_ == "Off") + { + struct stream_cfg rxcfg; + rxcfg.bw_hz = bandwidth_; + rxcfg.fs_hz = sample_rate_; + rxcfg.lo_hz = freq_; + rxcfg.rfport = rf_port_select_.c_str(); + + 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"); + } + } + else if (filter_source_ == "Auto") + { + ret = ad9361_set_bb_rate(ad9361_phy, sample_rate_); + if (ret) + { + throw std::runtime_error("Unable to set BB rate"); + // set bw + //params.push_back("in_voltage_rf_bandwidth=" + boost::to_string(bandwidth)); + } + //wr_ch_str(rx_chan1, "rf_port_select", rf_port_select_.c_str()); + ret = iio_device_attr_write(ad9361_phy, "in_voltage0_rf_port_select", rf_port_select_.c_str()); + if (ret) + { + throw std::runtime_error("Unable to set rf_port_select"); + } + wr_ch_lli(rx_chan1, "rf_bandwidth", bandwidth_); + if (!get_lo_chan(ctx, RX, &rx_chan1)) + { + return false; + } + wr_ch_lli(rx_chan1, "frequency", freq_); + } + else if (filter_source_ == "File") + { + try + { + if (!load_fir_filter(filter_filename_, ad9361_phy)) + { + throw std::runtime_error("Unable to load filter file"); + } + } + catch (const std::runtime_error &e) + { + std::cout << "Exception cached when configuring the RX FIR filter: " << e.what() << std::endl; + } + ret = iio_device_attr_write(ad9361_phy, "in_voltage0_rf_port_select", rf_port_select_.c_str()); + if (ret) + { + throw std::runtime_error("Unable to set rf_port_select"); + } + wr_ch_lli(rx_chan1, "rf_bandwidth", bandwidth_); + if (!get_lo_chan(ctx, RX, &rx_chan1)) + { + return false; + } + wr_ch_lli(rx_chan1, "frequency", freq_); + } + else if (filter_source_ == "Design") + { + ret = ad9361_set_bb_rate_custom_filter_manual( + ad9361_phy, sample_rate_, static_cast(Fpass_), static_cast(Fstop_), bandwidth_, bandwidth_); + if (ret) + { + throw std::runtime_error("Unable to set BB rate"); + } + ret = iio_device_attr_write(ad9361_phy, "in_voltage0_rf_port_select", rf_port_select_.c_str()); + if (ret) + { + throw std::runtime_error("Unable to set rf_port_select"); + } + wr_ch_lli(rx_chan1, "rf_bandwidth", bandwidth_); + if (!get_lo_chan(ctx, RX, &rx_chan1)) + { + return false; + } + wr_ch_lli(rx_chan1, "frequency", freq_); + } + else + { + throw std::runtime_error("Unknown filter configuration"); + } + + // Filters can only be disabled after the sample rate has been set + if (filter_source_ == "Off") + { + ret = ad9361_set_trx_fir_enable(ad9361_phy, false); + if (ret) + { + throw std::runtime_error("Unable to disable filters"); + } + } + std::cout << "* Enabling IIO streaming channels\n"; iio_channel_enable(rx_chan1); iio_channel_enable(rx_chan2); - 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) { @@ -322,13 +408,13 @@ bool config_ad9361_rx_remote(const std::string &remote_host, double rf_gain_rx2_, bool quadrature_, bool rfdc_, - bool bbdc_) + bool bbdc_, + std::string filter_source_, + std::string filter_filename_, + float Fpass_, + float Fstop_) { - std::string filter_source_("Off"); - float Fpass_ = 0.0, Fstop_ = 0.0; - std::string filter_filename_; // RX stream config - std::cout << "AD9361 Acquiring IIO REMOTE context in host " << remote_host << std::endl; struct iio_context *ctx; // Streaming devices diff --git a/src/algorithms/signal_source/libs/ad9361_manager.h b/src/algorithms/signal_source/libs/ad9361_manager.h index 7216ae4f8..0ca3d790a 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.h +++ b/src/algorithms/signal_source/libs/ad9361_manager.h @@ -92,7 +92,11 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, double rf_gain_rx2_, bool quadrature_, bool rfdc_, - bool bbdc_); + bool bbdc_, + std::string filter_source_, + std::string filter_filename_, + float Fpass_, + float Fstop_); bool config_ad9361_rx_remote(const std::string &remote_host, uint64_t bandwidth_, From fb0093aaab9314a614b192adbff191b25153141c Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 9 Oct 2019 21:13:28 +0200 Subject: [PATCH 11/19] clang-tidy: apply performance-unnecessary-value-param fix --- src/algorithms/signal_source/libs/ad9361_manager.cc | 4 ++-- src/algorithms/signal_source/libs/ad9361_manager.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index 9be96a771..caab16ddc 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -189,7 +189,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, bool quadrature_, bool rfdc_, bool bbdc_, - std::string filter_source_, + const std::string& filter_source_, std::string filter_filename_, float Fpass_, float Fstop_) @@ -409,7 +409,7 @@ bool config_ad9361_rx_remote(const std::string &remote_host, bool quadrature_, bool rfdc_, bool bbdc_, - std::string filter_source_, + const std::string& filter_source_, std::string filter_filename_, float Fpass_, float Fstop_) diff --git a/src/algorithms/signal_source/libs/ad9361_manager.h b/src/algorithms/signal_source/libs/ad9361_manager.h index 0ca3d790a..14cf90b9e 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.h +++ b/src/algorithms/signal_source/libs/ad9361_manager.h @@ -93,7 +93,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, bool quadrature_, bool rfdc_, bool bbdc_, - std::string filter_source_, + const std::string& filter_source_, std::string filter_filename_, float Fpass_, float Fstop_); From 54698bd2115e1a7438ab71ecf089b8c63e352156 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 9 Oct 2019 21:15:20 +0200 Subject: [PATCH 12/19] Apply clang-format --- src/algorithms/signal_source/libs/ad9361_manager.cc | 4 ++-- src/algorithms/signal_source/libs/ad9361_manager.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index caab16ddc..4a230e1b2 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -189,7 +189,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, bool quadrature_, bool rfdc_, bool bbdc_, - const std::string& filter_source_, + const std::string &filter_source_, std::string filter_filename_, float Fpass_, float Fstop_) @@ -409,7 +409,7 @@ bool config_ad9361_rx_remote(const std::string &remote_host, bool quadrature_, bool rfdc_, bool bbdc_, - const std::string& filter_source_, + const std::string &filter_source_, std::string filter_filename_, float Fpass_, float Fstop_) diff --git a/src/algorithms/signal_source/libs/ad9361_manager.h b/src/algorithms/signal_source/libs/ad9361_manager.h index 14cf90b9e..0dc2a54f6 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.h +++ b/src/algorithms/signal_source/libs/ad9361_manager.h @@ -93,7 +93,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, bool quadrature_, bool rfdc_, bool bbdc_, - const std::string& filter_source_, + const std::string &filter_source_, std::string filter_filename_, float Fpass_, float Fstop_); From b0c00eb5b0d421a28889a5d43eaba94f2a3d5d2a Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 9 Oct 2019 22:08:08 +0200 Subject: [PATCH 13/19] Fix for old versions of libad9361 --- CMakeLists.txt | 1 - .../signal_source/libs/CMakeLists.txt | 7 ++++ .../signal_source/libs/ad9361_manager.cc | 34 +++++++++++++++++-- .../signal_source/libs/ad9361_manager.h | 8 +++-- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1442b0692..2ed8556b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2292,7 +2292,6 @@ set_package_properties(LIBAD9361 PROPERTIES TYPE OPTIONAL ) if(NOT LIBAD9361_FOUND) - set(GRIIO_FOUND FALSE) set(ENABLE_AD9361 OFF) endif() if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index 48f8edb74..daffa40bb 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -70,6 +70,13 @@ if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) PRIVATE Iio::ad9361 ) + if(LIBAD9361_VERSION) + if(LIBAD9361_VERSION VERSION_GREATER 0.1) + target_compile_definitions(signal_source_libs + PUBLIC -DLIBAD9361_VERSION_GREATER_THAN_01=1 + ) + endif() + endif() endif() if(ENABLE_CLANG_TIDY) diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index 4a230e1b2..7d798fdb6 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -189,7 +189,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, bool quadrature_, bool rfdc_, bool bbdc_, - const std::string &filter_source_, + std::string filter_source_, std::string filter_filename_, float Fpass_, float Fstop_) @@ -204,6 +204,19 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, struct iio_channel *rx_chan2; int ret; +#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" << std::endl; + filter_source_ = std::string("Off"); + } + if (Fpass_ != 0.0 or Fstop_ != 0.0) + { + Fpass_ = 0.0; + Fstop_ = 0.0; + } +#endif + ctx = iio_create_default_context(); if (!ctx) { @@ -301,6 +314,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, } wr_ch_lli(rx_chan1, "frequency", freq_); } +#if LIBAD9361_VERSION_GREATER_THAN_01 else if (filter_source_ == "Design") { ret = ad9361_set_bb_rate_custom_filter_manual( @@ -321,6 +335,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, } wr_ch_lli(rx_chan1, "frequency", freq_); } +#endif else { throw std::runtime_error("Unknown filter configuration"); @@ -409,7 +424,7 @@ bool config_ad9361_rx_remote(const std::string &remote_host, bool quadrature_, bool rfdc_, bool bbdc_, - const std::string &filter_source_, + std::string filter_source_, std::string filter_filename_, float Fpass_, float Fstop_) @@ -422,6 +437,19 @@ bool config_ad9361_rx_remote(const std::string &remote_host, struct iio_channel *rx_chan1; struct iio_channel *rx_chan2; +#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" << std::endl; + filter_source_ = std::string("Off"); + } + if (Fpass_ != 0.0 or Fstop_ != 0.0) + { + Fpass_ = 0.0; + Fstop_ = 0.0; + } +#endif + ctx = iio_create_network_context(remote_host.c_str()); if (!ctx) { @@ -523,6 +551,7 @@ bool config_ad9361_rx_remote(const std::string &remote_host, } wr_ch_lli(rx_chan1, "frequency", freq_); } +#if LIBAD9361_VERSION_GREATER_THAN_01 else if (filter_source_ == "Design") { ret = ad9361_set_bb_rate_custom_filter_manual( @@ -543,6 +572,7 @@ bool config_ad9361_rx_remote(const std::string &remote_host, } wr_ch_lli(rx_chan1, "frequency", freq_); } +#endif else { throw std::runtime_error("Unknown filter configuration"); diff --git a/src/algorithms/signal_source/libs/ad9361_manager.h b/src/algorithms/signal_source/libs/ad9361_manager.h index 0dc2a54f6..897558da9 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.h +++ b/src/algorithms/signal_source/libs/ad9361_manager.h @@ -93,7 +93,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, bool quadrature_, bool rfdc_, bool bbdc_, - const std::string &filter_source_, + std::string filter_source_, std::string filter_filename_, float Fpass_, float Fstop_); @@ -109,7 +109,11 @@ bool config_ad9361_rx_remote(const std::string &remote_host, double rf_gain_rx2_, bool quadrature_, bool rfdc_, - bool bbdc_); + bool bbdc_, + std::string filter_source_, + std::string filter_filename_, + float Fpass_, + float Fstop_); bool config_ad9361_lo_local(uint64_t bandwidth_, uint64_t sample_rate_, From 7e823123a2c6461ecc7e98860591cd46d8deae23 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 9 Oct 2019 22:17:44 +0200 Subject: [PATCH 14/19] Improve doc provided in terminal --- src/algorithms/signal_source/adapters/CMakeLists.txt | 10 ++++++++++ .../signal_source/adapters/fmcomms2_signal_source.cc | 2 ++ .../signal_source/adapters/plutosdr_signal_source.cc | 2 ++ 3 files changed, 14 insertions(+) diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index c279601dd..de887cf10 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -189,6 +189,16 @@ if(ENABLE_AD9361 AND LIBIIO_FOUND) ) endif() +if(ENABLE_AD9361 OR ENABLE_FMCOMMS2 OR ENABLE_PLUTOSDR) + if(LIBAD9361_VERSION) + if(LIBAD9361_VERSION VERSION_GREATER 0.1) + target_compile_definitions(signal_source_adapters + PUBLIC -DLIBAD9361_VERSION_GREATER_THAN_01=1 + ) + endif() + endif() +endif() + if(ENABLE_FLEXIBAND AND TELEORBIT_FOUND) target_link_libraries(signal_source_adapters PRIVATE diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index 1d7a3f579..e251d5a26 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -133,7 +133,9 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration std::cout << " Off: Disable filter" << std::endl; std::cout << " Auto: Use auto-generated filters" << std::endl; std::cout << " File: User-provided filter in filter_filename parameter" << std::endl; +#if LIBAD9361_VERSION_GREATER_THAN_01 std::cout << " Design: Create filter from Fpass, Fstop, sampling_frequency and bandwidth parameters" << std::endl; +#endif std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values" << std::endl; std::cout << " This parameter has been set to its default value filter_source=Off" << std::endl; filter_source_ = std::string("Off"); diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc index 6d30aac99..679481146 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc @@ -107,7 +107,9 @@ PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration std::cout << " Off: Disable filter" << std::endl; std::cout << " Auto: Use auto-generated filters" << std::endl; std::cout << " File: User-provided filter in filter_filename parameter" << std::endl; +#if LIBAD9361_VERSION_GREATER_THAN_01 std::cout << " Design: Create filter from Fpass, Fstop, sampling_frequency and bandwidth parameters" << std::endl; +#endif std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values" << std::endl; std::cout << " This parameter has been set to its default value filter_source=Off" << std::endl; filter_source_ = std::string("Off"); From 94bef678af676722d3f02b395a2c13e7d6df2eee Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 9 Oct 2019 22:24:29 +0200 Subject: [PATCH 15/19] Set definition to PRIVATE --- src/algorithms/signal_source/adapters/CMakeLists.txt | 2 +- src/algorithms/signal_source/libs/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index de887cf10..bd0fa201a 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -193,7 +193,7 @@ if(ENABLE_AD9361 OR ENABLE_FMCOMMS2 OR ENABLE_PLUTOSDR) if(LIBAD9361_VERSION) if(LIBAD9361_VERSION VERSION_GREATER 0.1) target_compile_definitions(signal_source_adapters - PUBLIC -DLIBAD9361_VERSION_GREATER_THAN_01=1 + PRIVATE -DLIBAD9361_VERSION_GREATER_THAN_01=1 ) endif() endif() diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index daffa40bb..eab25b48a 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -73,7 +73,7 @@ if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) if(LIBAD9361_VERSION) if(LIBAD9361_VERSION VERSION_GREATER 0.1) target_compile_definitions(signal_source_libs - PUBLIC -DLIBAD9361_VERSION_GREATER_THAN_01=1 + PRIVATE -DLIBAD9361_VERSION_GREATER_THAN_01=1 ) endif() endif() From 8eca3f7cf019cac9a76148d7c75a2a9783d5612f Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 9 Oct 2019 22:55:20 +0200 Subject: [PATCH 16/19] Fix debian10 building --- src/algorithms/signal_source/libs/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index eab25b48a..dc3aa1d92 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -67,9 +67,13 @@ if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) target_link_libraries(signal_source_libs PUBLIC Iio::iio - PRIVATE - Iio::ad9361 ) + if(ENABLE_AD9361) + target_link_libraries(signal_source_libs + PRIVATE + Iio::ad9361 + ) + endif() if(LIBAD9361_VERSION) if(LIBAD9361_VERSION VERSION_GREATER 0.1) target_compile_definitions(signal_source_libs From a6c6e539823b68e7f8a6b43730e1ded286ddfd7b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 10 Oct 2019 07:38:27 +0200 Subject: [PATCH 17/19] Fix building in Debian Buster --- src/algorithms/signal_source/libs/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index dc3aa1d92..32a0f8179 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -17,7 +17,7 @@ # -if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) +if(ENABLE_AD9361) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ad9361_manager.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ad9361_manager.h) endif() From cb99011de8e22404c792724bbe3ab336bc4eb175 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 10 Oct 2019 08:12:25 +0200 Subject: [PATCH 18/19] Fix building --- .../signal_source/adapters/CMakeLists.txt | 7 +- .../adapters/fmcomms2_signal_source.cc | 196 +++++++++++++++++- .../adapters/fmcomms2_signal_source.h | 10 + 3 files changed, 204 insertions(+), 9 deletions(-) diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index bd0fa201a..63f74d68d 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -57,7 +57,7 @@ if(ENABLE_GN3S) # GN3S (USB dongle) ############################################## if(NOT GRGN3S_FOUND) - message(" gr-gn3s not found, install it from https://github.com/gnss-sdr/gr-gn3s ") + message(" gr-gn3s not found, install it from https://github.com/gnss-sdr/gr-gn3s") message(FATAL_ERROR "gr-gn3s required for building gnss-sdr with this option enabled") endif() set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} gn3s_signal_source.cc) @@ -76,7 +76,7 @@ if(ENABLE_ARRAY) # DBFCTTC GNSS EXPERIMENTAL ARRAY PROTOTYPE ############################################## if(NOT GRDBFCTTC_FOUND) - message(" gr-dbfcttc not found, install it from https://github.com/gnss-sdr/gr-dbfcttc ") + message(" gr-dbfcttc not found, install it from https://github.com/gnss-sdr/gr-dbfcttc") message(FATAL_ERROR "gr-dbfcttc required for building gnss-sdr with this option enabled") endif() set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} raw_array_signal_source.cc) @@ -220,7 +220,6 @@ if(ENABLE_ARRAY AND GRDBFCTTC_FOUND) ) endif() - if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) if(GR_IIO_INCLUDE_HAS_GNURADIO) target_compile_definitions(signal_source_adapters @@ -236,6 +235,8 @@ if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) PUBLIC Gnuradio::iio Boost::chrono + PRIVATE + Iio::iio ) endif() diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index e251d5a26..f5d00c917 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -32,18 +32,18 @@ #include "fmcomms2_signal_source.h" #include "GPS_L1_CA.h" #include "GPS_L2C.h" -#include "ad9361_manager.h" #include "configuration_interface.h" #include "gnss_sdr_valve.h" #include +#include #include // for max #include #include #include -Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration, - const std::string& role, unsigned int in_stream, unsigned int out_stream, +Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, unsigned int out_stream, std::shared_ptr> queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream), queue_(std::move(queue)) { std::string default_item_type = "gr_complex"; @@ -241,7 +241,7 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration scale_dds_dbfs_, phase_dds_deg_); } - catch (const std::runtime_error& e) + catch (const std::runtime_error &e) { std::cout << "Exception cached when configuring the TX carrier: " << e.what() << std::endl; } @@ -308,7 +308,7 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration scale_dds_dbfs_, phase_dds_deg_); } - catch (const std::runtime_error& e) + catch (const std::runtime_error &e) { std::cout << "Exception cached when configuring the TX carrier: " << e.what() << std::endl; } @@ -341,6 +341,190 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration } +bool Fmcomms2SignalSource::config_ad9361_lo_remote(const std::string &remote_host, + uint64_t bandwidth_, + uint64_t sample_rate_, + uint64_t freq_rf_tx_hz_, + double tx_attenuation_db_, + int64_t freq_dds_tx_hz_, + double scale_dds_dbfs_, + double phase_dds_deg_) +{ + // TX stream config + std::cout << "Start of AD9361 TX Local Oscillator DDS configuration\n"; + struct stream_cfg txcfg; + txcfg.bw_hz = bandwidth_; + txcfg.fs_hz = sample_rate_; + txcfg.lo_hz = freq_rf_tx_hz_; + txcfg.rfport = "A"; + + std::cout << "AD9361 Acquiring IIO REMOTE context in host " << remote_host << std::endl; + struct iio_context *ctx; + ctx = iio_create_network_context(remote_host.c_str()); + if (!ctx) + { + std::cout << "No context\n"; + throw std::runtime_error("AD9361 IIO No context"); + } + + // find tx device + struct iio_device *tx; + + std::cout << "* Acquiring AD9361 TX streaming devices\n"; + + if (!get_ad9361_stream_dev(ctx, TX, &tx)) + { + std::cout << "No tx dev found\n"; + throw std::runtime_error("AD9361 IIO No tx dev found"); + }; + + std::cout << "* Configuring AD9361 for streaming TX\n"; + if (!cfg_ad9361_streaming_ch(ctx, &txcfg, TX, 0)) + { + std::cout << "TX port 0 not found\n"; + throw std::runtime_error("AD9361 IIO TX port 0 not found"); + } + + // ENABLE DDS on TX1 + struct iio_device *ad9361_phy; + ad9361_phy = iio_context_find_device(ctx, "ad9361-phy"); + int ret; + // set output amplifier attenuation + ret = iio_device_attr_write_double(ad9361_phy, "out_voltage0_hardwaregain", -std::abs(tx_attenuation_db_)); + if (ret < 0) + { + std::cout << "Failed to set out_voltage0_hardwaregain value " << -std::abs(tx_attenuation_db_) << ". Error " << ret << std::endl; + } + + // shut down signal in TX2 + ret = iio_device_attr_write_double(ad9361_phy, "out_voltage1_hardwaregain", -89.75); + if (ret < 0) + { + std::cout << "Failed to set out_voltage1_hardwaregain value -89.75 dB. Error " << ret << std::endl; + } + struct iio_device *dds; + dds = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc"); + struct iio_channel *dds_channel0_I; + dds_channel0_I = iio_device_find_channel(dds, "TX1_I_F1", true); + + struct iio_channel *dds_channel0_Q; + dds_channel0_Q = iio_device_find_channel(dds, "TX1_Q_F1", true); + + ret = iio_channel_attr_write_bool(dds_channel0_I, "raw", true); + if (ret < 0) + { + std::cout << "Failed to toggle DDS: " << ret << std::endl; + } + + // set frequency, scale and phase + ret = iio_channel_attr_write_longlong(dds_channel0_I, "frequency", static_cast(freq_dds_tx_hz_)); + if (ret < 0) + { + std::cout << "Failed to set TX DDS frequency I: " << ret << std::endl; + } + + ret = iio_channel_attr_write_longlong(dds_channel0_Q, "frequency", static_cast(freq_dds_tx_hz_)); + if (ret < 0) + { + std::cout << "Failed to set TX DDS frequency Q: " << ret << std::endl; + } + + ret = iio_channel_attr_write_double(dds_channel0_I, "phase", phase_dds_deg_ * 1000.0); + if (ret < 0) + { + std::cout << "Failed to set TX DDS phase I: " << ret << std::endl; + } + + ret = iio_channel_attr_write_double(dds_channel0_Q, "phase", phase_dds_deg_ * 1000.0 + 270000.0); + if (ret < 0) + { + std::cout << "Failed to set TX DDS phase Q: " << ret << std::endl; + } + + ret = iio_channel_attr_write_double(dds_channel0_I, "scale", pow(10, scale_dds_dbfs_ / 20.0)); + if (ret < 0) + { + std::cout << "Failed to set TX DDS scale I: " << ret << std::endl; + } + + ret = iio_channel_attr_write_double(dds_channel0_Q, "scale", pow(10, scale_dds_dbfs_ / 20.0)); + if (ret < 0) + { + std::cout << "Failed to set TX DDS scale Q: " << ret << std::endl; + } + + // disable TX2 + ret = iio_device_attr_write_double(ad9361_phy, "out_voltage1_hardwaregain", -89.0); + if (ret < 0) + { + std::cout << "Failed to set out_voltage1_hardwaregain value " << -89.0 << " error " << ret << std::endl; + } + + struct iio_channel *dds_channel1_I; + dds_channel1_I = iio_device_find_channel(dds, "TX2_I_F1", true); + + struct iio_channel *dds_channel1_Q; + dds_channel1_Q = iio_device_find_channel(dds, "TX2_Q_F1", true); + + ret = iio_channel_attr_write_double(dds_channel1_I, "scale", 0); + if (ret < 0) + { + std::cout << "Failed to set TX2 DDS scale I: " << ret << std::endl; + } + + ret = iio_channel_attr_write_double(dds_channel1_Q, "scale", 0); + if (ret < 0) + { + std::cout << "Failed to set TX2 DDS scale Q: " << ret << std::endl; + } + + iio_context_destroy(ctx); + return true; +} + + +bool Fmcomms2SignalSource::ad9361_disable_lo_remote(const std::string &remote_host) +{ + std::cout << "AD9361 Acquiring IIO REMOTE context in host " << remote_host << std::endl; + struct iio_context *ctx; + ctx = iio_create_network_context(remote_host.c_str()); + if (!ctx) + { + std::cout << "No context\n"; + throw std::runtime_error("AD9361 IIO No context"); + } + struct iio_device *dds; + dds = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc"); + struct iio_channel *dds_channel0_I; + dds_channel0_I = iio_device_find_channel(dds, "TX1_I_F1", true); + + struct iio_channel *dds_channel0_Q; + dds_channel0_Q = iio_device_find_channel(dds, "TX1_Q_F1", true); + int ret; + ret = iio_channel_attr_write_bool(dds_channel0_I, "raw", false); + if (ret < 0) + { + std::cout << "Failed to toggle DDS: " << ret << std::endl; + } + + ret = iio_channel_attr_write_double(dds_channel0_I, "scale", 0.0); + if (ret < 0) + { + std::cout << "Failed to set TX DDS scale I: " << ret << std::endl; + } + + ret = iio_channel_attr_write_double(dds_channel0_Q, "scale", 0.0); + if (ret < 0) + { + std::cout << "Failed to set TX DDS scale Q: " << ret << std::endl; + } + + iio_context_destroy(ctx); + + return true; +} + + Fmcomms2SignalSource::~Fmcomms2SignalSource() { if (enable_dds_lo_ == true) @@ -349,7 +533,7 @@ Fmcomms2SignalSource::~Fmcomms2SignalSource() { ad9361_disable_lo_remote(uri_); } - catch (const std::exception& e) + catch (const std::exception &e) { LOG(WARNING) << "Exception thrown in Fmcomms2SignalSource destructor: " << e.what(); } diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h index cc08bfc47..32423dadc 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h @@ -82,6 +82,16 @@ public: gr::basic_block_sptr get_right_block() override; private: + bool config_ad9361_lo_remote(const std::string &remote_host, + uint64_t bandwidth, + uint64_t sample_rate, + uint64_t freq_rf_tx_hz, + double tx_attenuation_db, + int64_t freq_dds_tx_hz, + double scale_dds_dbfs, + double phase_dds_deg); + + bool ad9361_disable_lo_remote(const std::string &remote_host); std::string role_; // Front-end settings From 3f2136758752dc3b62a5fc2f4d10f253733ea946 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 10 Oct 2019 10:40:37 +0200 Subject: [PATCH 19/19] Fix building in some configurations --- CMakeLists.txt | 5 +- .../adapters/fmcomms2_signal_source.cc | 186 +----------------- .../adapters/fmcomms2_signal_source.h | 10 - .../signal_source/libs/CMakeLists.txt | 10 +- 4 files changed, 7 insertions(+), 204 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ed8556b2..b4fd3a937 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2293,6 +2293,7 @@ set_package_properties(LIBAD9361 PROPERTIES ) if(NOT LIBAD9361_FOUND) set(ENABLE_AD9361 OFF) + set(ENABLE_FMCOMMS2 OFF) endif() if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) if(NOT GRIIO_FOUND) @@ -2574,9 +2575,9 @@ 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_FMCOMMS2 ENABLE_FMCOMMS2 "Enables Fmcomms2_Signal_Source for FMCOMMS2/3/4 devices. Requires gr-iio.") +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.") +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_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_GN3S ENABLE_GN3S "Enables Gn3s_Signal_Source for using the GN3S v2 dongle. Requires gr-gn3s.") diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index f5d00c917..87065525e 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -32,10 +32,10 @@ #include "fmcomms2_signal_source.h" #include "GPS_L1_CA.h" #include "GPS_L2C.h" +#include "ad9361_manager.h" #include "configuration_interface.h" #include "gnss_sdr_valve.h" #include -#include #include // for max #include #include @@ -341,190 +341,6 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface *configuration } -bool Fmcomms2SignalSource::config_ad9361_lo_remote(const std::string &remote_host, - uint64_t bandwidth_, - uint64_t sample_rate_, - uint64_t freq_rf_tx_hz_, - double tx_attenuation_db_, - int64_t freq_dds_tx_hz_, - double scale_dds_dbfs_, - double phase_dds_deg_) -{ - // TX stream config - std::cout << "Start of AD9361 TX Local Oscillator DDS configuration\n"; - struct stream_cfg txcfg; - txcfg.bw_hz = bandwidth_; - txcfg.fs_hz = sample_rate_; - txcfg.lo_hz = freq_rf_tx_hz_; - txcfg.rfport = "A"; - - std::cout << "AD9361 Acquiring IIO REMOTE context in host " << remote_host << std::endl; - struct iio_context *ctx; - ctx = iio_create_network_context(remote_host.c_str()); - if (!ctx) - { - std::cout << "No context\n"; - throw std::runtime_error("AD9361 IIO No context"); - } - - // find tx device - struct iio_device *tx; - - std::cout << "* Acquiring AD9361 TX streaming devices\n"; - - if (!get_ad9361_stream_dev(ctx, TX, &tx)) - { - std::cout << "No tx dev found\n"; - throw std::runtime_error("AD9361 IIO No tx dev found"); - }; - - std::cout << "* Configuring AD9361 for streaming TX\n"; - if (!cfg_ad9361_streaming_ch(ctx, &txcfg, TX, 0)) - { - std::cout << "TX port 0 not found\n"; - throw std::runtime_error("AD9361 IIO TX port 0 not found"); - } - - // ENABLE DDS on TX1 - struct iio_device *ad9361_phy; - ad9361_phy = iio_context_find_device(ctx, "ad9361-phy"); - int ret; - // set output amplifier attenuation - ret = iio_device_attr_write_double(ad9361_phy, "out_voltage0_hardwaregain", -std::abs(tx_attenuation_db_)); - if (ret < 0) - { - std::cout << "Failed to set out_voltage0_hardwaregain value " << -std::abs(tx_attenuation_db_) << ". Error " << ret << std::endl; - } - - // shut down signal in TX2 - ret = iio_device_attr_write_double(ad9361_phy, "out_voltage1_hardwaregain", -89.75); - if (ret < 0) - { - std::cout << "Failed to set out_voltage1_hardwaregain value -89.75 dB. Error " << ret << std::endl; - } - struct iio_device *dds; - dds = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc"); - struct iio_channel *dds_channel0_I; - dds_channel0_I = iio_device_find_channel(dds, "TX1_I_F1", true); - - struct iio_channel *dds_channel0_Q; - dds_channel0_Q = iio_device_find_channel(dds, "TX1_Q_F1", true); - - ret = iio_channel_attr_write_bool(dds_channel0_I, "raw", true); - if (ret < 0) - { - std::cout << "Failed to toggle DDS: " << ret << std::endl; - } - - // set frequency, scale and phase - ret = iio_channel_attr_write_longlong(dds_channel0_I, "frequency", static_cast(freq_dds_tx_hz_)); - if (ret < 0) - { - std::cout << "Failed to set TX DDS frequency I: " << ret << std::endl; - } - - ret = iio_channel_attr_write_longlong(dds_channel0_Q, "frequency", static_cast(freq_dds_tx_hz_)); - if (ret < 0) - { - std::cout << "Failed to set TX DDS frequency Q: " << ret << std::endl; - } - - ret = iio_channel_attr_write_double(dds_channel0_I, "phase", phase_dds_deg_ * 1000.0); - if (ret < 0) - { - std::cout << "Failed to set TX DDS phase I: " << ret << std::endl; - } - - ret = iio_channel_attr_write_double(dds_channel0_Q, "phase", phase_dds_deg_ * 1000.0 + 270000.0); - if (ret < 0) - { - std::cout << "Failed to set TX DDS phase Q: " << ret << std::endl; - } - - ret = iio_channel_attr_write_double(dds_channel0_I, "scale", pow(10, scale_dds_dbfs_ / 20.0)); - if (ret < 0) - { - std::cout << "Failed to set TX DDS scale I: " << ret << std::endl; - } - - ret = iio_channel_attr_write_double(dds_channel0_Q, "scale", pow(10, scale_dds_dbfs_ / 20.0)); - if (ret < 0) - { - std::cout << "Failed to set TX DDS scale Q: " << ret << std::endl; - } - - // disable TX2 - ret = iio_device_attr_write_double(ad9361_phy, "out_voltage1_hardwaregain", -89.0); - if (ret < 0) - { - std::cout << "Failed to set out_voltage1_hardwaregain value " << -89.0 << " error " << ret << std::endl; - } - - struct iio_channel *dds_channel1_I; - dds_channel1_I = iio_device_find_channel(dds, "TX2_I_F1", true); - - struct iio_channel *dds_channel1_Q; - dds_channel1_Q = iio_device_find_channel(dds, "TX2_Q_F1", true); - - ret = iio_channel_attr_write_double(dds_channel1_I, "scale", 0); - if (ret < 0) - { - std::cout << "Failed to set TX2 DDS scale I: " << ret << std::endl; - } - - ret = iio_channel_attr_write_double(dds_channel1_Q, "scale", 0); - if (ret < 0) - { - std::cout << "Failed to set TX2 DDS scale Q: " << ret << std::endl; - } - - iio_context_destroy(ctx); - return true; -} - - -bool Fmcomms2SignalSource::ad9361_disable_lo_remote(const std::string &remote_host) -{ - std::cout << "AD9361 Acquiring IIO REMOTE context in host " << remote_host << std::endl; - struct iio_context *ctx; - ctx = iio_create_network_context(remote_host.c_str()); - if (!ctx) - { - std::cout << "No context\n"; - throw std::runtime_error("AD9361 IIO No context"); - } - struct iio_device *dds; - dds = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc"); - struct iio_channel *dds_channel0_I; - dds_channel0_I = iio_device_find_channel(dds, "TX1_I_F1", true); - - struct iio_channel *dds_channel0_Q; - dds_channel0_Q = iio_device_find_channel(dds, "TX1_Q_F1", true); - int ret; - ret = iio_channel_attr_write_bool(dds_channel0_I, "raw", false); - if (ret < 0) - { - std::cout << "Failed to toggle DDS: " << ret << std::endl; - } - - ret = iio_channel_attr_write_double(dds_channel0_I, "scale", 0.0); - if (ret < 0) - { - std::cout << "Failed to set TX DDS scale I: " << ret << std::endl; - } - - ret = iio_channel_attr_write_double(dds_channel0_Q, "scale", 0.0); - if (ret < 0) - { - std::cout << "Failed to set TX DDS scale Q: " << ret << std::endl; - } - - iio_context_destroy(ctx); - - return true; -} - - Fmcomms2SignalSource::~Fmcomms2SignalSource() { if (enable_dds_lo_ == true) diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h index 32423dadc..cc08bfc47 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h @@ -82,16 +82,6 @@ public: gr::basic_block_sptr get_right_block() override; private: - bool config_ad9361_lo_remote(const std::string &remote_host, - uint64_t bandwidth, - uint64_t sample_rate, - uint64_t freq_rf_tx_hz, - double tx_attenuation_db, - int64_t freq_dds_tx_hz, - double scale_dds_dbfs, - double phase_dds_deg); - - bool ad9361_disable_lo_remote(const std::string &remote_host); std::string role_; // Front-end settings diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index 32a0f8179..eea22e84e 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -17,7 +17,7 @@ # -if(ENABLE_AD9361) +if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ad9361_manager.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ad9361_manager.h) endif() @@ -67,13 +67,9 @@ if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) target_link_libraries(signal_source_libs PUBLIC Iio::iio - ) - if(ENABLE_AD9361) - target_link_libraries(signal_source_libs - PRIVATE - Iio::ad9361 + PRIVATE + Iio::ad9361 ) - endif() if(LIBAD9361_VERSION) if(LIBAD9361_VERSION VERSION_GREATER 0.1) target_compile_definitions(signal_source_libs