1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-06-18 11:09:56 +00:00

Add energy-saving options for AD9361

New flag rf_shutdown, true by default, allows setting the RX and TX streams ON when set to false.
New parameters rx1_enable and rx2_enable, true by default, allow to disable the secondary RX channel when not used
This commit is contained in:
Carles Fernandez 2019-10-13 23:38:06 +02:00
parent 3c49792aef
commit a9b0ff184d
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
8 changed files with 177 additions and 34 deletions

View File

@ -59,6 +59,8 @@ DEFINE_string(s, "-",
DEFINE_string(signal_source, "-",
"If defined, path to the file containing the signal samples (overrides the configuration file).");
DEFINE_bool(rf_shutdown, true, "If set to false, AD9361 RF channels are not shut down when exiting the program. Useful to leave the AD9361 configured and running.");
DEFINE_int32(doppler_max, 0, "If defined, sets the maximum Doppler value in the search grid, in Hz (overrides the configuration file).");
DEFINE_int32(doppler_step, 0, "If defined, sets the frequency step in the search grid, in Hz (overrides the configuration file).");

View File

@ -42,6 +42,7 @@ DECLARE_string(log_dir); //!< Path to the folder in which logging will be store
// Declare flags for signal sources
DECLARE_string(s); //!< Path to the file containing the signal samples.
DECLARE_string(signal_source); //!< Path to the file containing the signal samples.
DECLARE_bool(rf_shutdown); //!< Shutdown RF when program exits.
// Declare flags for acquisition blocks
DECLARE_int32(doppler_max); //!< If defined, maximum Doppler value in the search grid, in Hz (overrides the configuration file).

View File

@ -35,6 +35,7 @@
#include "GPS_L5.h"
#include "ad9361_manager.h"
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include <glog/logging.h>
#include <iio.h>
#include <algorithm> // for max
@ -291,6 +292,8 @@ 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);
rx1_enable_ = configuration->property(role + ".rx1_enable", true);
rx2_enable_ = configuration->property(role + ".rx2_enable", true);
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);
@ -317,6 +320,8 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura
tx_bandwidth_ = configuration->property(role + ".tx_bandwidth", 500000);
phase_dds_deg_ = configuration->property(role + ".phase_dds_deg", 0.0);
rf_shutdown_ = configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown);
// turn switch to A/D position
std::string default_device_name = "/dev/uio1";
std::string device_name = configuration->property(role + ".devicename", default_device_name);
@ -449,6 +454,8 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura
sample_rate_,
freq_,
rf_port_select_,
rx1_enable_,
rx2_enable_,
gain_mode_rx1_,
gain_mode_rx2_,
rf_gain_rx1_,
@ -515,33 +522,37 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface *configura
Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource()
{
/* cleanup and exit */
// std::cout<<"* AD9361 Disabling streaming channels\n";
// if (rx0_i) { iio_channel_disable(rx0_i); }
// if (rx0_q) { iio_channel_disable(rx0_q); }
enable_DMA_ = false; // disable the DMA
if (enable_dds_lo_)
{
try
{
ad9361_disable_lo_local();
}
catch (const std::exception &e)
{
LOG(WARNING) << "Problem closing the Ad9361FpgaSignalSource: " << e.what();
}
}
if (switch_position == 0) // read samples from a file via DMA
{
enable_DMA_ = false; // disable the DMA
if (thread_file_to_dma.joinable())
{
thread_file_to_dma.join();
}
}
// std::cout<<"* AD9361 Destroying context\n";
// if (ctx) { iio_context_destroy(ctx); }
if (switch_position == 2) // Real-time via AD9361
{
if (rf_shutdown_)
{
std::cout << "* AD9361 Disabling RX streaming channels\n";
if (!disable_ad9361_rx_local())
{
LOG(WARNING) << "Problem shutting down the AD9361 RX channels";
}
if (enable_dds_lo_)
{
try
{
ad9361_disable_lo_local();
}
catch (const std::exception &e)
{
LOG(WARNING) << "Problem shutting down the AD9361 TX stream: " << e.what();
}
}
}
}
}

View File

@ -86,6 +86,8 @@ private:
bool quadrature_;
bool rf_dc_;
bool bb_dc_;
bool rx1_enable_;
bool rx2_enable_;
std::string gain_mode_rx1_;
std::string gain_mode_rx2_;
double rf_gain_rx1_;
@ -123,6 +125,7 @@ private:
std::string freq_band;
bool enable_DMA_;
bool rf_shutdown_;
};
#endif // GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H_

View File

@ -34,6 +34,7 @@
#include "GPS_L2C.h"
#include "ad9361_manager.h"
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include "gnss_sdr_valve.h"
#include <glog/logging.h>
#include <algorithm> // for max
@ -94,6 +95,8 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface *configuration
tx_attenuation_db_ = configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db);
tx_bandwidth_ = configuration->property(role + ".tx_bandwidth", 500000);
rf_shutdown_ = configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown);
item_size_ = sizeof(gr_complex);
// some basic checks
@ -343,15 +346,22 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface *configuration
Fmcomms2SignalSource::~Fmcomms2SignalSource()
{
if (enable_dds_lo_ == true)
if (rf_shutdown_)
{
try
if (!disable_ad9361_rx_remote(uri_))
{
ad9361_disable_lo_remote(uri_);
LOG(WARNING) << "Problem shutting down the AD9361 RX channels";
}
catch (const std::exception &e)
if (enable_dds_lo_ == true)
{
LOG(WARNING) << "Exception thrown in Fmcomms2SignalSource destructor: " << e.what();
try
{
ad9361_disable_lo_remote(uri_);
}
catch (const std::exception &e)
{
LOG(WARNING) << "Problem shutting down the AD9361 TX channel: " << e.what();
}
}
}
}

View File

@ -56,7 +56,7 @@ public:
const std::string& role, unsigned int in_stream,
unsigned int out_stream, std::shared_ptr<Concurrent_Queue<pmt::pmt_t>> queue);
virtual ~Fmcomms2SignalSource();
~Fmcomms2SignalSource();
inline std::string role() override
{
@ -107,6 +107,7 @@ private:
std::string filter_filename_;
float Fpass_;
float Fstop_;
bool rf_shutdown_;
// DDS configuration for LO generation for external mixer
bool enable_dds_lo_;

View File

@ -182,6 +182,8 @@ bool config_ad9361_rx_local(uint64_t bandwidth_,
uint64_t sample_rate_,
uint64_t freq_,
const std::string &rf_port_select_,
bool rx1_enable_,
bool rx2_enable_,
const std::string &gain_mode_rx1_,
const std::string &gain_mode_rx2_,
double rf_gain_rx1_,
@ -238,7 +240,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_,
{
std::cout << "No rx dev found\n";
throw std::runtime_error("AD9361 IIO No rx dev found");
};
}
std::cout << "* Initializing AD9361 IIO streaming channels\n";
if (!get_ad9361_stream_ch(ctx, RX, rx, 0, &rx_chan1))
@ -352,8 +354,18 @@ bool config_ad9361_rx_local(uint64_t bandwidth_,
}
std::cout << "* Enabling IIO streaming channels\n";
iio_channel_enable(rx_chan1);
iio_channel_enable(rx_chan2);
if (rx1_enable_)
{
iio_channel_enable(rx_chan1);
}
if (rx2_enable_)
{
iio_channel_enable(rx_chan2);
}
if (!rx1_enable_ and !rx2_enable_)
{
std::cout << "WARNING: No Rx channels enabled.\n";
}
ret = iio_device_attr_write(ad9361_phy, "trx_rate_governor", "nominal");
if (ret < 0)
@ -417,6 +429,8 @@ bool config_ad9361_rx_remote(const std::string &remote_host,
uint64_t sample_rate_,
uint64_t freq_,
const std::string &rf_port_select_,
bool rx1_enable_,
bool rx2_enable_,
const std::string &gain_mode_rx1_,
const std::string &gain_mode_rx2_,
double rf_gain_rx1_,
@ -469,7 +483,7 @@ bool config_ad9361_rx_remote(const std::string &remote_host,
{
std::cout << "No rx dev found\n";
throw std::runtime_error("AD9361 IIO No rx dev found");
};
}
std::cout << "* Configuring AD9361 for streaming\n";
@ -589,8 +603,18 @@ bool config_ad9361_rx_remote(const std::string &remote_host,
}
std::cout << "* Enabling IIO streaming channels\n";
iio_channel_enable(rx_chan1);
iio_channel_enable(rx_chan2);
if (rx1_enable_)
{
iio_channel_enable(rx_chan1);
}
if (rx2_enable_)
{
iio_channel_enable(rx_chan2);
}
if (!rx1_enable_ and !rx2_enable_)
{
std::cout << "WARNING: No Rx channels enabled.\n";
}
ret = iio_device_attr_write(ad9361_phy, "trx_rate_governor", "nominal");
if (ret < 0)
@ -690,7 +714,7 @@ bool config_ad9361_lo_local(uint64_t bandwidth_,
{
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))
@ -832,7 +856,7 @@ bool config_ad9361_lo_remote(const std::string &remote_host,
{
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))
@ -1065,3 +1089,86 @@ bool load_fir_filter(
return ret > 0;
}
bool disable_ad9361_rx_local()
{
struct iio_context *ctx;
struct iio_device *rx;
struct iio_channel *rx_chan1;
struct iio_channel *rx_chan2;
ctx = iio_create_default_context();
if (!ctx)
{
std::cout << "No default context available when disabling RX channels\n";
return false;
}
if (iio_context_get_devices_count(ctx) <= 0)
{
std::cout << "No devices available when disabling RX channels\n";
return false;
}
if (!get_ad9361_stream_dev(ctx, RX, &rx))
{
std::cout << "No rx streams found when disabling RX channels\n";
return false;
}
if (!get_ad9361_stream_ch(ctx, RX, rx, 0, &rx_chan1))
{
std::cout << "RX channel 1 not found when disabling RX channels\n";
return false;
}
if (!get_ad9361_stream_ch(ctx, RX, rx, 1, &rx_chan2))
{
std::cout << "RX channel 2 not found when disabling RX channels\n";
return false;
}
iio_channel_disable(rx_chan1);
iio_channel_disable(rx_chan2);
iio_context_destroy(ctx);
return true;
}
bool disable_ad9361_rx_remote(const std::string &remote_host)
{
struct iio_context *ctx;
struct iio_device *rx;
struct iio_channel *rx_chan1;
struct iio_channel *rx_chan2;
ctx = iio_create_network_context(remote_host.c_str());
if (!ctx)
{
std::cout << "No context available at " << remote_host << "when disabling RX channels\n";
return false;
}
if (!get_ad9361_stream_dev(ctx, RX, &rx))
{
std::cout << "No rx streams found at " << remote_host << " when disabling RX channels\n";
return false;
}
if (!get_ad9361_stream_ch(ctx, RX, rx, 0, &rx_chan1))
{
std::cout << "RX channel 1 not found at " << remote_host << " when disabling RX channels\n";
return false;
}
if (!get_ad9361_stream_ch(ctx, RX, rx, 1, &rx_chan2))
{
std::cout << "RX channel 2 not found at " << remote_host << " when disabling RX channels\n";
return false;
}
iio_channel_disable(rx_chan1);
iio_channel_disable(rx_chan2);
iio_context_destroy(ctx);
return true;
}

View File

@ -86,6 +86,8 @@ bool config_ad9361_rx_local(uint64_t bandwidth_,
uint64_t sample_rate_,
uint64_t freq_,
const std::string &rf_port_select_,
bool rx1_enable_,
bool rx2_enable_,
const std::string &gain_mode_rx1_,
const std::string &gain_mode_rx2_,
double rf_gain_rx1_,
@ -103,6 +105,8 @@ bool config_ad9361_rx_remote(const std::string &remote_host,
uint64_t sample_rate_,
uint64_t freq_,
const std::string &rf_port_select_,
bool rx1_enable_,
bool rx2_enable_,
const std::string &gain_mode_rx1_,
const std::string &gain_mode_rx2_,
double rf_gain_rx1_,
@ -138,4 +142,8 @@ bool ad9361_disable_lo_local();
bool load_fir_filter(std::string &filter, struct iio_device *phy);
bool disable_ad9361_rx_local();
bool disable_ad9361_rx_remote(const std::string &remote_host);
#endif // GNSS_SDR_AD9361_MANAGER_H_