1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-04-07 03:07:02 +00:00

Adding ad936x custom source optional interchannel delay compensation

This commit is contained in:
Javier Arribas 2022-09-13 17:34:23 +02:00
parent 4ac556fdb8
commit dd1ce7893c
6 changed files with 314 additions and 102 deletions

View File

@ -62,7 +62,10 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface*
inverted_spectrum_ch0_(configuration->property(role + ".inverted_spectrum_ch0", false)),
inverted_spectrum_ch1_(configuration->property(role + ".inverted_spectrum_ch1", false)),
lo_attenuation_db_(configuration->property(role + ".lo_attenuation_db", 6.0)),
high_side_lo_(configuration->property(role + ".high_side_lo", false))
high_side_lo_(configuration->property(role + ".high_side_lo", false)),
tx_lo_channel_(configuration->property(role + ".tx_lo_channel", 1)),
rx0_to_rx1_delay_ns_(configuration->property(role + ".rx0_to_rx1_delay_ns", 0.0))
{
if (item_type_ == "gr_complex")
@ -99,7 +102,8 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface*
bshift_,
spattern_,
lo_attenuation_db_,
high_side_lo_);
high_side_lo_,
tx_lo_channel_);
n_channels = 1;
if (enable_ch0 == true and enable_ch1 == true)
@ -107,6 +111,42 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface*
n_channels = 2;
}
int delay_samples = 0;
if (n_channels == 2 and rx0_to_rx1_delay_ns_ != 0.0)
{
double ts = 1.0 / static_cast<double>(sample_rate_);
delay_samples = std::round(ts * rx0_to_rx1_delay_ns_ * 1e-9);
if (delay_samples != 0)
{
delay_enabled = true;
if (delay_samples > 0)
{
apply_delay_on_rx0 = true;
LOG(INFO) << " Instantiating delay of rx0 equal to " << delay_samples << " samples.";
}
else
{
// delay applied to rx1 instead.
apply_delay_on_rx0 = false;
delay_samples = -delay_samples;
LOG(INFO) << " Instantiating delay of rx1 equal to " << delay_samples << " samples.";
}
}
else
{
LOG(INFO) << " Specified rx0_to_rx1 delay is smaller than the front-end sample period.";
}
}
else
{
apply_delay_on_rx0 = false;
delay_enabled = false;
}
if (delay_enabled == true)
{
gr_delay = gr::blocks::delay::make(sizeof(gr_complex), delay_samples);
}
for (int n = 0; n < n_channels; n++)
{
@ -175,10 +215,44 @@ void Ad936xCustomSignalSource::connect(gr::top_block_sptr top_block)
{
top_block->connect(ad936x_iio_source, n, gr_interleaved_short_to_complex_.at(n), 0);
DLOG(INFO) << "connected ad936x_iio_source source to gr_interleaved_short_to_complex for channel " << n;
if (dump_)
if (delay_enabled == true)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
if (n == 0 and apply_delay_on_rx0 == true)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, gr_delay, 0);
DLOG(INFO) << "connected gr_interleaved_short_to_complex to gr_delay for channel " << n;
if (dump_)
{
top_block->connect(gr_delay, 0, sink_.at(n), 0);
DLOG(INFO) << "connected delayed source to file sink";
}
}
else if (n == 1 and apply_delay_on_rx0 == false)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, gr_delay, 0);
DLOG(INFO) << "connected gr_interleaved_short_to_complex to gr_delay for channel " << n;
if (dump_)
{
top_block->connect(gr_delay, 0, sink_.at(n), 0);
DLOG(INFO) << "connected delayed source to file sink";
}
}
else
{
if (dump_)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
}
else
{
if (dump_)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
}
else if (ssize_ == 8)
@ -186,11 +260,44 @@ void Ad936xCustomSignalSource::connect(gr::top_block_sptr top_block)
top_block->connect(ad936x_iio_source, n, unpack_short_byte.at(n), 0);
top_block->connect(unpack_short_byte.at(n), 0, gr_char_to_short_.at(n), 0);
top_block->connect(gr_char_to_short_.at(n), 0, gr_interleaved_short_to_complex_.at(n), 0);
DLOG(INFO) << "connected ad936x_iio_source source to gr_interleaved_short_to_complex_ for channel " << n;
if (dump_)
if (delay_enabled == true)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
if (n == 0 and apply_delay_on_rx0 == true)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, gr_delay, 0);
DLOG(INFO) << "connected gr_interleaved_short_to_complex to gr_delay for channel " << n;
if (dump_)
{
top_block->connect(gr_delay, 0, sink_.at(n), 0);
DLOG(INFO) << "connected delayed source to file sink";
}
}
else if (n == 1 and apply_delay_on_rx0 == false)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, gr_delay, 0);
DLOG(INFO) << "connected gr_interleaved_short_to_complex to gr_delay for channel " << n;
if (dump_)
{
top_block->connect(gr_delay, 0, sink_.at(n), 0);
DLOG(INFO) << "connected delayed source to file sink";
}
}
else
{
if (dump_)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
}
else
{
if (dump_)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
}
else if (ssize_ == 4)
@ -199,10 +306,45 @@ void Ad936xCustomSignalSource::connect(gr::top_block_sptr top_block)
top_block->connect(unpack_short_byte.at(n), 0, unpack_byte_fourbits.at(n), 0);
top_block->connect(unpack_byte_fourbits.at(n), 0, gr_interleaved_short_to_complex_.at(n), 0);
DLOG(INFO) << "connected ad936x_iio_source source to unpack_byte_fourbits for channel " << n;
if (dump_)
if (delay_enabled == true)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
if (n == 0 and apply_delay_on_rx0 == true)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, gr_delay, 0);
DLOG(INFO) << "connected gr_interleaved_short_to_complex to gr_delay for channel " << n;
if (dump_)
{
top_block->connect(gr_delay, 0, sink_.at(n), 0);
DLOG(INFO) << "connected delayed source to file sink";
}
}
else if (n == 1 and apply_delay_on_rx0 == false)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, gr_delay, 0);
DLOG(INFO) << "connected gr_interleaved_short_to_complex to gr_delay for channel " << n;
if (dump_)
{
top_block->connect(gr_delay, 0, sink_.at(n), 0);
DLOG(INFO) << "connected delayed source to file sink";
}
}
else
{
if (dump_)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
}
else
{
if (dump_)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
}
else if (ssize_ == 2)
@ -211,20 +353,91 @@ void Ad936xCustomSignalSource::connect(gr::top_block_sptr top_block)
top_block->connect(unpack_short_byte.at(n), 0, unpack_byte_twobits.at(n), 0);
top_block->connect(unpack_byte_twobits.at(n), 0, gr_interleaved_short_to_complex_.at(n), 0);
DLOG(INFO) << "connected ad936x_iio_source source to unpack_byte_fourbits for channel " << n;
if (dump_)
if (delay_enabled == true)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
if (n == 0 and apply_delay_on_rx0 == true)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, gr_delay, 0);
DLOG(INFO) << "connected gr_interleaved_short_to_complex to gr_delay for channel " << n;
if (dump_)
{
top_block->connect(gr_delay, 0, sink_.at(n), 0);
DLOG(INFO) << "connected delayed source to file sink";
}
}
else if (n == 1 and apply_delay_on_rx0 == false)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, gr_delay, 0);
DLOG(INFO) << "connected gr_interleaved_short_to_complex to gr_delay for channel " << n;
if (dump_)
{
top_block->connect(gr_delay, 0, sink_.at(n), 0);
DLOG(INFO) << "connected delayed source to file sink";
}
}
else
{
if (dump_)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
}
else
{
if (dump_)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
}
else
{
top_block->connect(ad936x_iio_source, n, gr_interleaved_short_to_complex_.at(n), 0);
DLOG(INFO) << "connected ad936x_iio_source source to gr_interleaved_short_to_complex for channel " << n;
if (dump_)
if (delay_enabled == true)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
if (n == 0 and apply_delay_on_rx0 == true)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, gr_delay, 0);
DLOG(INFO) << "connected gr_interleaved_short_to_complex to gr_delay for channel " << n;
if (dump_)
{
top_block->connect(gr_delay, 0, sink_.at(n), 0);
DLOG(INFO) << "connected delayed source to file sink";
}
}
else if (n == 1 and apply_delay_on_rx0 == false)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, gr_delay, 0);
DLOG(INFO) << "connected gr_interleaved_short_to_complex to gr_delay for channel " << n;
if (dump_)
{
top_block->connect(gr_delay, 0, sink_.at(n), 0);
DLOG(INFO) << "connected delayed source to file sink";
}
}
else
{
if (dump_)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
}
else
{
if (dump_)
{
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
}
}
@ -304,45 +517,25 @@ gr::basic_block_sptr Ad936xCustomSignalSource::get_left_block()
gr::basic_block_sptr Ad936xCustomSignalSource::get_right_block()
{
if (ssize_ == 16)
{
return gr_interleaved_short_to_complex_.at(0);
}
else if (ssize_ == 8)
{
return gr_interleaved_short_to_complex_.at(0);
}
else if (ssize_ == 4)
{
return gr_interleaved_short_to_complex_.at(0);
}
else if (ssize_ == 2)
{
return gr_interleaved_short_to_complex_.at(0);
}
else
{
return gr_interleaved_short_to_complex_.at(0);
}
return gr_interleaved_short_to_complex_.at(0);
}
gr::basic_block_sptr Ad936xCustomSignalSource::get_right_block(int RF_channel)
{
if (ssize_ == 16)
if (delay_enabled == true)
{
return gr_interleaved_short_to_complex_.at(RF_channel);
}
else if (ssize_ == 8)
{
return gr_interleaved_short_to_complex_.at(RF_channel);
}
else if (ssize_ == 4)
{
return gr_interleaved_short_to_complex_.at(RF_channel);
}
else if (ssize_ == 2)
{
return gr_interleaved_short_to_complex_.at(RF_channel);
if (RF_channel == 0 and apply_delay_on_rx0 == true)
{
return gr_delay;
}
else if (RF_channel == 1 and apply_delay_on_rx0 == false)
{
return gr_delay;
}
else
{
return gr_interleaved_short_to_complex_.at(RF_channel);
}
}
else
{

View File

@ -27,6 +27,7 @@
#include <gnuradio/blocks/char_to_short.h>
#include <gnuradio/blocks/file_sink.h>
// #include <gnuradio/blocks/interleaved_char_to_complex.h>
#include <gnuradio/blocks/delay.h>
#include <gnuradio/blocks/interleaved_short_to_complex.h>
#include <pmt/pmt.h>
#include <cstdint>
@ -74,6 +75,7 @@ private:
std::vector<gr::blocks::file_sink::sptr> sink_;
std::vector<std::string> filename_vec_;
gr::blocks::delay::sptr gr_delay;
std::vector<gr::blocks::char_to_short::sptr> gr_char_to_short_;
std::vector<gr::blocks::interleaved_short_to_complex::sptr> gr_interleaved_short_to_complex_;
// std::vector<gr::blocks::interleaved_char_to_complex::sptr> gr_interleaved_char_to_complex_;
@ -113,6 +115,10 @@ private:
bool inverted_spectrum_ch1_;
double lo_attenuation_db_;
bool high_side_lo_;
int tx_lo_channel_;
double rx0_to_rx1_delay_ns_;
bool delay_enabled;
bool apply_delay_on_rx0;
std::vector<bool> inverted_spectrum_vec;
int n_channels;

View File

@ -55,7 +55,8 @@ ad936x_iio_source_sptr ad936x_iio_make_source_sptr(
int bshift_,
bool spattern_,
double lo_attenuation_db_,
bool high_side_lo_)
bool high_side_lo_,
int tx_lo_channel_)
{
return ad936x_iio_source_sptr(new ad936x_iio_source(
pluto_uri_,
@ -80,7 +81,8 @@ ad936x_iio_source_sptr ad936x_iio_make_source_sptr(
bshift_,
spattern_,
lo_attenuation_db_,
high_side_lo_));
high_side_lo_,
tx_lo_channel_));
}
void ad936x_iio_source::ad9361_channel_demux_and_record(ad936x_iio_samples *samples_in, int nchannels, std::vector<std::fstream> *files_out)
@ -122,7 +124,8 @@ ad936x_iio_source::ad936x_iio_source(
int bshift_,
bool spattern_,
double lo_attenuation_db_,
bool high_side_lo_) : gr::block("ad936x_iio_source",
bool high_side_lo_,
int tx_lo_channel_) : gr::block("ad936x_iio_source",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(1, 4, sizeof(int16_t)))
{
@ -145,7 +148,8 @@ ad936x_iio_source::ad936x_iio_source(
enable_ch1,
freq_2ch,
lo_attenuation_db_,
high_side_lo_) == true)
high_side_lo_,
tx_lo_channel_) == true)
{
std::cout << "ad936x_iio_source HW configured OK!\n";

View File

@ -66,7 +66,8 @@ ad936x_iio_source_sptr ad936x_iio_make_source_sptr(
int bshift_,
bool spattern_,
double lo_attenuation_db_,
bool high_side_lo_);
bool high_side_lo_,
int tx_lo_channel_);
/*!
* \brief This class implements conversion between Labsat 2, 3 and 3 Wideband
@ -111,7 +112,8 @@ private:
int bshift_,
bool spattern_,
double lo_attenuation_db_,
bool high_side_lo_);
bool high_side_lo_,
int tx_lo_channel_);
ad936x_iio_source(
std::string pluto_uri_,
@ -136,7 +138,8 @@ private:
int bshift_,
bool spattern_,
double lo_attenuation_db_,
bool high_side_lo_);
bool high_side_lo_,
int tx_lo_channel_);
void ad9361_channel_demux_to_buffer(ad936x_iio_samples *samples_in, int nchannels, gr_vector_void_star &output_items);

View File

@ -258,17 +258,39 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_,
// ENABLE DDS on TX1
// Configure LO channel
std::vector<std::string> params_phy;
std::vector<std::string> params_dds;
params_phy.push_back("out_altvoltage1_TX_LO_frequency=" +
std::to_string(freq_rf_tx_hz_));
double disabled_tx_attenuation = 89.75;
if (channel == 1)
if (channel == 0)
{
params_phy.push_back("out_voltage0_hardwaregain=" +
std::to_string(-tx_attenuation_db_));
//disable the other TX
params_phy.push_back("out_voltage1_hardwaregain=" +
std::to_string(-disabled_tx_attenuation));
configure_params(phy, params_phy);
//DDS TX CH1 I (tone #1)
params_dds.push_back("out_altvoltage0_TX1_I_F1_frequency=" +
std::to_string(freq_dds_tx_hz_));
params_dds.push_back("out_altvoltage0_TX1_I_F1_phase=" +
std::to_string(phase_dds_deg_ * 1000.0));
params_dds.push_back("out_altvoltage0_TX1_I_F1_scale=" +
std::to_string(scale_dds_));
params_dds.push_back("out_altvoltage0_TX1_I_F1_raw=1");
//DDS TX CH1 Q (tone #1)
params_dds.push_back("out_altvoltage2_TX1_Q_F1_frequency=" +
std::to_string(freq_dds_tx_hz_));
params_dds.push_back("out_altvoltage2_TX1_Q_F1_phase=" +
std::to_string(phase_dds_deg_ * 1000.0 + 270000.0));
params_dds.push_back("out_altvoltage2_TX1_Q_F1_scale=" +
std::to_string(scale_dds_));
params_dds.push_back("out_altvoltage2_TX1_Q_F1_raw=1");
configure_params(dds_dev, params_dds);
}
else
{
@ -277,46 +299,29 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_,
//disable the other TX
params_phy.push_back("out_voltage0_hardwaregain=" +
std::to_string(-disabled_tx_attenuation));
configure_params(phy, params_phy);
//DDS TX CH2 I (tone #1)
params_dds.push_back("out_altvoltage4_TX2_I_F1_frequency=" +
std::to_string(freq_dds_tx_hz_));
params_dds.push_back("out_altvoltage4_TX2_I_F1_phase=" +
std::to_string(phase_dds_deg_ * 1000.0));
params_dds.push_back("out_altvoltage4_TX2_I_F1_scale=" +
std::to_string(scale_dds_));
params_dds.push_back("out_altvoltage4_TX2_I_F1_raw=1");
//DDS TX CH2 Q (tone #1)
params_dds.push_back("out_altvoltage6_TX2_Q_F1_frequency=" +
std::to_string(freq_dds_tx_hz_));
params_dds.push_back("out_altvoltage6_TX2_Q_F1_phase=" +
std::to_string(phase_dds_deg_ * 1000.0 + 270000.0));
params_dds.push_back("out_altvoltage6_TX2_Q_F1_scale=" +
std::to_string(scale_dds_));
params_dds.push_back("out_altvoltage6_TX2_Q_F1_raw=1");
configure_params(dds_dev, params_dds);
}
configure_params(phy, params_phy);
std::vector<std::string> params_dds;
//DDS TX CH1 I (tone #1)
// params_dds.push_back("out_altvoltage0_TX1_I_F1_frequency=" +
// std::to_string(freq_dds_tx_hz_));
// params_dds.push_back("out_altvoltage0_TX1_I_F1_phase=" +
// std::to_string(phase_dds_deg_ * 1000.0));
// params_dds.push_back("out_altvoltage0_TX1_I_F1_scale=" +
// std::to_string(scale_dds_));
// params_dds.push_back("out_altvoltage0_TX1_I_F1_raw=1");
// //DDS TX CH1 Q (tone #1)
// params_dds.push_back("out_altvoltage2_TX1_Q_F1_frequency=" +
// std::to_string(freq_dds_tx_hz_));
// params_dds.push_back("out_altvoltage2_TX1_Q_F1_phase=" +
// std::to_string(phase_dds_deg_ * 1000.0 + 270000.0));
// params_dds.push_back("out_altvoltage2_TX1_Q_F1_scale=" +
// std::to_string(scale_dds_));
// params_dds.push_back("out_altvoltage2_TX1_Q_F1_raw=1");
//DDS TX CH2 I (tone #1)
params_dds.push_back("out_altvoltage4_TX2_I_F1_frequency=" +
std::to_string(freq_dds_tx_hz_));
params_dds.push_back("out_altvoltage4_TX2_I_F1_phase=" +
std::to_string(phase_dds_deg_ * 1000.0));
params_dds.push_back("out_altvoltage4_TX2_I_F1_scale=" +
std::to_string(scale_dds_));
params_dds.push_back("out_altvoltage4_TX2_I_F1_raw=1");
//DDS TX CH2 Q (tone #1)
params_dds.push_back("out_altvoltage6_TX2_Q_F1_frequency=" +
std::to_string(freq_dds_tx_hz_));
params_dds.push_back("out_altvoltage6_TX2_Q_F1_phase=" +
std::to_string(phase_dds_deg_ * 1000.0 + 270000.0));
params_dds.push_back("out_altvoltage6_TX2_Q_F1_scale=" +
std::to_string(scale_dds_));
params_dds.push_back("out_altvoltage6_TX2_Q_F1_raw=1");
configure_params(dds_dev, params_dds);
return true;
}
@ -412,7 +417,8 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
bool enable_ch1,
long long freq_2ch,
double lo_attenuation_db_,
bool high_side_lo_)
bool high_side_lo_,
int tx_lo_channel_)
{
if (check_device() == false) return false;
@ -541,7 +547,7 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
0,
0.9,
0,
2);
tx_lo_channel_);
std::cout << "Configuring DDS Local Oscillator generation DONE\n";
}
else

View File

@ -55,7 +55,8 @@ public:
bool enable_ch1,
long long freq_2ch,
double lo_attenuation_db_,
bool high_side_lo_);
bool high_side_lo_,
int tx_lo_channel_);
bool calibrate(int ch, double bw_hz);
@ -79,7 +80,6 @@ public:
void pop_sample_buffer(std::shared_ptr<ad936x_iio_samples> &current_buffer);
void push_sample_buffer(std::shared_ptr<ad936x_iio_samples> &current_buffer);
int n_channels;
private: