1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-03-05 02:58:16 +00:00

Adding extra control for the AD936x custom source external mixer

This commit is contained in:
Javier Arribas 2022-08-30 15:28:18 +02:00
parent f20a696f8a
commit 0c5d38145f
6 changed files with 138 additions and 71 deletions

View File

@ -56,12 +56,13 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface*
PPS_mode_(configuration->property(role + ".PPS_mode", false)),
fe_ip_(configuration->property(role + ".fe_ip", std::string("192.168.2.1"))),
fe_ctlport_(configuration->property(role + ".fe_ctlport", int32_t(10000))),
ssize_(configuration->property(role + ".ssize", int32_t(16))),
ssize_(configuration->property(role + ".ssize", int32_t(12))),
bshift_(configuration->property(role + ".bshift", int64_t(0))),
spattern_(configuration->property(role + ".spattern", false)),
inverted_spectrum_ch0_(configuration->property(role + ".inverted_spectrum_ch0", false)),
inverted_spectrum_ch1_(configuration->property(role + ".inverted_spectrum_ch1", 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))
{
if (item_type_ == "gr_complex")
@ -69,7 +70,11 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface*
item_size_ = sizeof(gr_complex);
// 1. Make the driver instance
bool customsamplesize = false;
if (ssize_ != 16 or spattern_ == true) customsamplesize = true;
if (ssize_ != 12 or spattern_ == true) customsamplesize = true; // custom FPGA DMA firmware
if (ssize_ == 12) // default original FPGA DMA firmware
{
ssize_ = 16; // set to 16 bits and do not try to change sample size
}
ad936x_iio_source = ad936x_iio_make_source_sptr(
pluto_uri_,
@ -92,7 +97,9 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface*
fe_ctlport_,
ssize_,
bshift_,
spattern_);
spattern_,
lo_attenuation_db_,
high_side_lo_);
n_channels = 1;
if (enable_ch0 == true and enable_ch1 == true)
@ -100,26 +107,34 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface*
n_channels = 2;
}
for (int n = 0; n < n_channels; n++)
{
if (n == 0) inverted_spectrum_vec.push_back(inverted_spectrum_ch0_);
if (n == 1) inverted_spectrum_vec.push_back(inverted_spectrum_ch1_);
}
for (int n = 0; n < n_channels; n++)
{
if (ssize_ == 16)
{
gr_interleaved_short_to_complex_.push_back(gr::blocks::interleaved_short_to_complex::make());
gr_interleaved_short_to_complex_.push_back(gr::blocks::interleaved_short_to_complex::make(false, inverted_spectrum_vec.at(n)));
}
else if (ssize_ == 8)
{
gr_interleaved_char_to_complex_.push_back(gr::blocks::interleaved_char_to_complex::make());
unpack_short_byte.push_back(make_unpack_short_byte_samples());
gr_char_to_short_.push_back(gr::blocks::char_to_short::make());
gr_interleaved_short_to_complex_.push_back(gr::blocks::interleaved_short_to_complex::make(false, inverted_spectrum_vec.at(n)));
}
else if (ssize_ == 4)
{
gr_interleaved_short_to_complex_.push_back(gr::blocks::interleaved_short_to_complex::make(false, false));
gr_interleaved_short_to_complex_.push_back(gr::blocks::interleaved_short_to_complex::make(false, inverted_spectrum_vec.at(n)));
unpack_byte_fourbits.push_back(make_unpack_byte_4bit_samples());
unpack_short_byte.push_back(make_unpack_short_byte_samples());
}
else if (ssize_ == 2)
{
gr_interleaved_short_to_complex_.push_back(gr::blocks::interleaved_short_to_complex::make(false, false));
gr_interleaved_short_to_complex_.push_back(gr::blocks::interleaved_short_to_complex::make(false, inverted_spectrum_vec.at(n)));
unpack_byte_twobits.push_back(make_unpack_byte_2bit_cpx_samples());
unpack_short_byte.push_back(make_unpack_short_byte_samples());
}
@ -169,11 +184,12 @@ void Ad936xCustomSignalSource::connect(gr::top_block_sptr top_block)
else if (ssize_ == 8)
{
top_block->connect(ad936x_iio_source, n, unpack_short_byte.at(n), 0);
top_block->connect(unpack_short_byte.at(n), 0, gr_interleaved_char_to_complex_.at(n), 0);
DLOG(INFO) << "connected ad936x_iio_source source to gr_interleaved_char_to_complex_ for channel " << n;
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_)
{
top_block->connect(gr_interleaved_char_to_complex_.at(n), 0, sink_.at(n), 0);
top_block->connect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
@ -231,13 +247,14 @@ void Ad936xCustomSignalSource::disconnect(gr::top_block_sptr top_block)
}
else if (ssize_ == 8)
{
top_block->connect(ad936x_iio_source, n, unpack_short_byte.at(n), 0);
top_block->connect(unpack_short_byte.at(n), 0, unpack_byte_fourbits.at(n), 0);
DLOG(INFO) << "disconnect ad936x_iio_source source to gr_interleaved_char_to_complex_ for channel " << n;
top_block->disconnect(ad936x_iio_source, n, unpack_short_byte.at(n), 0);
top_block->disconnect(unpack_short_byte.at(n), 0, gr_char_to_short_.at(n), 0);
top_block->disconnect(gr_char_to_short_.at(n), 0, gr_interleaved_short_to_complex_.at(n), 0);
DLOG(INFO) << "disconnect ad936x_iio_source source to gr_interleaved_short_to_complex_ for channel " << n;
if (dump_)
{
top_block->disconnect(gr_interleaved_char_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "disconnect source to file sink";
top_block->disconnect(gr_interleaved_short_to_complex_.at(n), 0, sink_.at(n), 0);
DLOG(INFO) << "connected source to file sink";
}
}
else if (ssize_ == 4)
@ -293,7 +310,7 @@ gr::basic_block_sptr Ad936xCustomSignalSource::get_right_block()
}
else if (ssize_ == 8)
{
return gr_interleaved_char_to_complex_.at(0);
return gr_interleaved_short_to_complex_.at(0);
}
else if (ssize_ == 4)
{
@ -317,7 +334,7 @@ gr::basic_block_sptr Ad936xCustomSignalSource::get_right_block(int RF_channel)
}
else if (ssize_ == 8)
{
return gr_interleaved_char_to_complex_.at(RF_channel);
return gr_interleaved_short_to_complex_.at(RF_channel);
}
else if (ssize_ == 4)
{

View File

@ -24,8 +24,9 @@
#include "unpack_byte_2bit_cpx_samples.h"
#include "unpack_byte_4bit_samples.h"
#include "unpack_short_byte_samples.h"
#include <gnuradio/blocks/char_to_short.h>
#include <gnuradio/blocks/file_sink.h>
#include <gnuradio/blocks/interleaved_char_to_complex.h>
// #include <gnuradio/blocks/interleaved_char_to_complex.h>
#include <gnuradio/blocks/interleaved_short_to_complex.h>
#include <pmt/pmt.h>
#include <cstdint>
@ -73,8 +74,9 @@ private:
std::vector<gr::blocks::file_sink::sptr> sink_;
std::vector<std::string> filename_vec_;
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_;
// std::vector<gr::blocks::interleaved_char_to_complex::sptr> gr_interleaved_char_to_complex_;
std::vector<unpack_short_byte_samples_sptr> unpack_short_byte;
std::vector<unpack_byte_4bit_samples_sptr> unpack_byte_fourbits;
std::vector<unpack_byte_2bit_cpx_samples_sptr> unpack_byte_twobits;
@ -109,8 +111,10 @@ private:
bool spattern_;
bool inverted_spectrum_ch0_;
bool inverted_spectrum_ch1_;
double lo_attenuation_db_;
bool high_side_lo_;
std::vector<bool> inverted_spectrum_vec;
int n_channels;
};

View File

@ -53,7 +53,9 @@ ad936x_iio_source_sptr ad936x_iio_make_source_sptr(
int fe_ctlport_,
int ssize_,
int bshift_,
bool spattern_)
bool spattern_,
double lo_attenuation_db_,
bool high_side_lo_)
{
return ad936x_iio_source_sptr(new ad936x_iio_source(
pluto_uri_,
@ -76,7 +78,9 @@ ad936x_iio_source_sptr ad936x_iio_make_source_sptr(
fe_ctlport_,
ssize_,
bshift_,
spattern_));
spattern_,
lo_attenuation_db_,
high_side_lo_));
}
void ad936x_iio_source::ad9361_channel_demux_and_record(ad936x_iio_samples *samples_in, int nchannels, std::vector<std::fstream> *files_out)
@ -116,9 +120,11 @@ ad936x_iio_source::ad936x_iio_source(
int fe_ctlport_,
int ssize_,
int bshift_,
bool spattern_) : gr::block("ad936x_iio_source",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(1, 4, sizeof(int16_t)))
bool spattern_,
double lo_attenuation_db_,
bool high_side_lo_) : gr::block("ad936x_iio_source",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(1, 4, sizeof(int16_t)))
{
ad936x_custom = std::make_unique<ad936x_iio_custom>(0, 0);
try
@ -137,7 +143,9 @@ ad936x_iio_source::ad936x_iio_source(
rf_gain_rx1_,
enable_ch0,
enable_ch1,
freq_2ch) == true)
freq_2ch,
lo_attenuation_db_,
high_side_lo_) == true)
{
std::cout << "ad936x_iio_source HW configured OK!\n";

View File

@ -64,7 +64,9 @@ ad936x_iio_source_sptr ad936x_iio_make_source_sptr(
int fe_ctlport_,
int ssize_,
int bshift_,
bool spattern_);
bool spattern_,
double lo_attenuation_db_,
bool high_side_lo_);
/*!
* \brief This class implements conversion between Labsat 2, 3 and 3 Wideband
@ -107,7 +109,9 @@ private:
int fe_ctlport_,
int ssize_,
int bshift_,
bool spattern_);
bool spattern_,
double lo_attenuation_db_,
bool high_side_lo_);
ad936x_iio_source(
std::string pluto_uri_,
@ -130,7 +134,9 @@ private:
int fe_ctlport_,
int ssize_,
int bshift_,
bool spattern_);
bool spattern_,
double lo_attenuation_db_,
bool high_side_lo_);
void ad9361_channel_demux_to_buffer(ad936x_iio_samples *samples_in, int nchannels, gr_vector_void_star &output_items);

View File

@ -410,7 +410,9 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
double rf_gain_rx1_,
bool enable_ch0,
bool enable_ch1,
long long freq_2ch)
long long freq_2ch,
double lo_attenuation_db_,
bool high_side_lo_)
{
if (check_device() == false) return false;
@ -510,17 +512,32 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
if (enable_ch1 == true and enable_ch0 == true and freq_ != freq_2ch)
{
std::cout << "Two channels enabled with different frequencies, enabling the external RF transverter board:\n";
long long int delta_freq_hz = freq_2ch - freq_;
if (delta_freq_hz < 0)
long long int lo_freq_hz = 0;
if (high_side_lo_ == false)
{
std::cout << "Configuration problem: 2nd channel frequency is " << freq_2ch << " [Hz], must be higher than main channel (" << freq_ << " [Hz])\n";
return false;
std::cout << "Using LOW SIDE Local Oscillator (F_RF > F_LO)\n";
lo_freq_hz = freq_2ch - freq_;
if (lo_freq_hz < 0)
{
std::cout << "Configuration problem: 2nd channel frequency is " << freq_2ch << " [Hz], must be higher than main channel (" << freq_ << " [Hz])\n";
return false;
}
}
else
{
std::cout << "Using HIGH SIDE Local Oscillator (F_RF < F_LO), consider baseband spectrum inversion.\n";
lo_freq_hz = freq_2ch + freq_;
if (lo_freq_hz < 0)
{
std::cout << "Configuration problem: 2nd channel frequency is " << freq_2ch << " [Hz], must be higher than main channel (" << freq_ << " [Hz])\n";
return false;
}
}
std::cout << "Configuring DDS Local Oscillator generation. LO Freq. is " << delta_freq_hz << " [Hz]\n";
std::cout << "Configuring DDS Local Oscillator generation. LO Freq. is " << lo_freq_hz << " [Hz]\n";
PlutoTxEnable(true);
config_ad9361_dds(delta_freq_hz,
0,
config_ad9361_dds(lo_freq_hz,
lo_attenuation_db_,
0,
0.9,
0,
@ -532,6 +549,30 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
PlutoTxEnable(false); //power down the TX LO to reduce interferences
}
int set_filter_ret = ad9361_set_bb_rate_custom_filter_auto(phy, sample_rate_sps);
if (set_filter_ret != 0)
{
std::cout << "Warning: Unable to set AD936x RX filter parameters!\n";
}
//testing: set manual RX filter chain
// unsigned long RX_analog_bb_lpf_stop_hz = 1000000;
// unsigned long TX_analog_bb_lpf_stop_hz = 1000000;
//
// unsigned long FIR_lpf_passband_hz = 1000000;
// unsigned long FIR_lpf_stopband_hz = 1200000;
// int set_filter_ret = ad9361_set_bb_rate_custom_filter_manual(phy,
// sample_rate_sps,
// FIR_lpf_passband_hz,
// FIR_lpf_stopband_hz,
// RX_analog_bb_lpf_stop_hz,
// TX_analog_bb_lpf_stop_hz);
// if (set_filter_ret != 0)
// {
// std::cout << "Warning: Unable to set AD936x RX filter parameters!\n";
// }
if (enable_ch0 == true)
{
n_channels++;
@ -555,12 +596,12 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
no_errors = false;
}
ret = iio_channel_attr_write_longlong(phy_ch, "rf_bandwidth", bandwidth_);
if (ret < 0)
{
std::cerr << "Warning: rf_bandwidth write returned: " << ret << "\n";
no_errors = false;
}
// ret = iio_channel_attr_write_longlong(phy_ch, "rf_bandwidth", bandwidth_);
// if (ret < 0)
// {
// std::cerr << "Warning: rf_bandwidth write returned: " << ret << "\n";
// no_errors = false;
// }
long long set_rf_bw;
ret = iio_channel_attr_read_longlong(phy_ch, "rf_bandwidth", &set_rf_bw);
@ -605,12 +646,24 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
no_errors = false;
}
ret = iio_channel_attr_write_longlong(phy_ch, "rf_bandwidth", bandwidth_);
// ret = iio_channel_attr_write_longlong(phy_ch, "rf_bandwidth", bandwidth_);
// if (ret < 0)
// {
// std::cerr << "Warning: rf_bandwidth write returned: " << ret << "\n";
// no_errors = false;
// }
long long set_rf_bw;
ret = iio_channel_attr_read_longlong(phy_ch, "rf_bandwidth", &set_rf_bw);
if (ret < 0)
{
std::cerr << "Warning: rf_bandwidth write returned: " << ret << "\n";
std::cerr << "Warning: rf_bandwidth read returned: " << ret << "\n";
no_errors = false;
}
else
{
std::cerr << "Info: rf_bandwidth read returned: " << set_rf_bw << " Hz \n";
}
if (setRXGain(1, gain_mode_rx1_, rf_gain_rx1_) == false)
{
@ -619,29 +672,6 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_,
}
}
int set_filter_ret = ad9361_set_bb_rate_custom_filter_auto(phy, sample_rate_sps);
if (set_filter_ret != 0)
{
std::cout << "Warning: Unable to set AD936x RX filter parameters!\n";
}
//testing: set manual RX filter chain
// unsigned long RX_analog_bb_lpf_stop_hz = 1000000;
// unsigned long TX_analog_bb_lpf_stop_hz = 1000000;
//
// unsigned long FIR_lpf_passband_hz = 1000000;
// unsigned long FIR_lpf_stopband_hz = 1200000;
// int set_filter_ret = ad9361_set_bb_rate_custom_filter_manual(phy,
// sample_rate_sps,
// FIR_lpf_passband_hz,
// FIR_lpf_stopband_hz,
// RX_analog_bb_lpf_stop_hz,
// TX_analog_bb_lpf_stop_hz);
// if (set_filter_ret != 0)
// {
// std::cout << "Warning: Unable to set AD936x RX filter parameters!\n";
// }
std::cout << "AD936x Front-end configuration summary: \n";
std::cout << "RF frequency tunned in AD936x: " << freq_ << " [Hz]\n";
std::cout << "Baseband sampling frequency: " << sample_rate_sps << " [SPS]\n";

View File

@ -53,7 +53,9 @@ public:
double rf_gain_rx1_,
bool enable_ch0,
bool enable_ch1,
long long freq_2ch);
long long freq_2ch,
double lo_attenuation_db_,
bool high_side_lo_);
bool calibrate(int ch, double bw_hz);