1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-11-14 05:44:56 +00:00

Replaced the AD9361 FPGA signal source with the ADRV9361_Z7035 FPGA and the FMCOMMS5 FPGA signal sources.

This commit is contained in:
Marc Majoral 2024-07-30 22:28:52 +02:00
parent c5bd9b6a03
commit 19a152c6ce
No known key found for this signature in database
GPG Key ID: 9D82A95A8E140375
8 changed files with 525 additions and 34 deletions

View File

@ -37,8 +37,10 @@ if(ENABLE_AD9361)
############################################### ###############################################
# AD9361 DIRECT TO FPGA Hardware # AD9361 DIRECT TO FPGA Hardware
############################################### ###############################################
list(APPEND OPT_DRIVER_SOURCES ad9361_signal_source_fpga.cc) list(APPEND OPT_DRIVER_SOURCES adrv9361_z7035_signal_source_fpga.cc)
list(APPEND OPT_DRIVER_HEADERS ad9361_signal_source_fpga.h) list(APPEND OPT_DRIVER_HEADERS adrv9361_z7035_signal_source_fpga.h)
list(APPEND OPT_DRIVER_SOURCES fmcomms5_signal_source_fpga.cc)
list(APPEND OPT_DRIVER_HEADERS fmcomms5_signal_source_fpga.h)
endif() endif()
if(ENABLE_MAX2771) if(ENABLE_MAX2771)

View File

@ -1,7 +1,7 @@
/*! /*!
* \file ad9361_signal_source_fpga.cc * \file adrv9361_z7035_signal_source_fpga.cc
* \brief signal source for Analog Devices front-end AD9361 connected directly * \brief signal source for the Analog Devices ADRV9361-Z7035 evaluation board
* to FPGA accelerators. * directly connected to the FPGA accelerators.
* This source implements only the AD9361 control. It is NOT compatible with * This source implements only the AD9361 control. It is NOT compatible with
* conventional SDR acquisition and tracking blocks. * conventional SDR acquisition and tracking blocks.
* Please use the fmcomms2 source if conventional SDR acquisition and tracking * Please use the fmcomms2 source if conventional SDR acquisition and tracking
@ -16,13 +16,13 @@
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR. * This file is part of GNSS-SDR.
* *
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* ----------------------------------------------------------------------------- * -----------------------------------------------------------------------------
*/ */
#include "ad9361_signal_source_fpga.h" #include "adrv9361_z7035_signal_source_fpga.h"
#include "GPS_L1_CA.h" #include "GPS_L1_CA.h"
#include "GPS_L5.h" #include "GPS_L5.h"
#include "ad9361_manager.h" #include "ad9361_manager.h"
@ -44,10 +44,10 @@
using namespace std::string_literals; using namespace std::string_literals;
Ad9361SignalSourceFPGA::Ad9361SignalSourceFPGA(const ConfigurationInterface *configuration, Adrv9361z7035SignalSourceFPGA::Adrv9361z7035SignalSourceFPGA(const ConfigurationInterface *configuration,
const std::string &role, unsigned int in_stream, unsigned int out_stream, const std::string &role, unsigned int in_stream, unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused))) Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused)))
: SignalSourceBase(configuration, role, "Ad9361_Signal_Source_Fpga"s), : SignalSourceBase(configuration, role, "ADRV9361_Z7035_Signal_Source_FPGA"s),
gain_mode_rx1_(configuration->property(role + ".gain_mode_rx1", default_gain_mode)), gain_mode_rx1_(configuration->property(role + ".gain_mode_rx1", default_gain_mode)),
gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)), gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)),
rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)), rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)),
@ -276,7 +276,7 @@ Ad9361SignalSourceFPGA::Ad9361SignalSourceFPGA(const ConfigurationInterface *con
} }
Ad9361SignalSourceFPGA::~Ad9361SignalSourceFPGA() Adrv9361z7035SignalSourceFPGA::~Adrv9361z7035SignalSourceFPGA()
{ {
/* cleanup and exit */ /* cleanup and exit */
@ -328,7 +328,7 @@ Ad9361SignalSourceFPGA::~Ad9361SignalSourceFPGA()
} }
void Ad9361SignalSourceFPGA::run_dynamic_bit_selection_process() void Adrv9361z7035SignalSourceFPGA::run_dynamic_bit_selection_process()
{ {
bool dynamic_bit_selection_active = true; bool dynamic_bit_selection_active = true;
@ -347,7 +347,7 @@ void Ad9361SignalSourceFPGA::run_dynamic_bit_selection_process()
} }
void Ad9361SignalSourceFPGA::run_buffer_monitor_process() void Adrv9361z7035SignalSourceFPGA::run_buffer_monitor_process()
{ {
bool enable_ovf_check_buffer_monitor_active = true; bool enable_ovf_check_buffer_monitor_active = true;
@ -367,7 +367,7 @@ void Ad9361SignalSourceFPGA::run_buffer_monitor_process()
} }
void Ad9361SignalSourceFPGA::connect(gr::top_block_sptr top_block) void Adrv9361z7035SignalSourceFPGA::connect(gr::top_block_sptr top_block)
{ {
if (top_block) if (top_block)
{ /* top_block is not null */ { /* top_block is not null */
@ -376,7 +376,7 @@ void Ad9361SignalSourceFPGA::connect(gr::top_block_sptr top_block)
} }
void Ad9361SignalSourceFPGA::disconnect(gr::top_block_sptr top_block) void Adrv9361z7035SignalSourceFPGA::disconnect(gr::top_block_sptr top_block)
{ {
if (top_block) if (top_block)
{ /* top_block is not null */ { /* top_block is not null */
@ -385,14 +385,14 @@ void Ad9361SignalSourceFPGA::disconnect(gr::top_block_sptr top_block)
} }
gr::basic_block_sptr Ad9361SignalSourceFPGA::get_left_block() gr::basic_block_sptr Adrv9361z7035SignalSourceFPGA::get_left_block()
{ {
LOG(WARNING) << "Trying to get signal source left block."; LOG(WARNING) << "Trying to get signal source left block.";
return {}; return {};
} }
gr::basic_block_sptr Ad9361SignalSourceFPGA::get_right_block() gr::basic_block_sptr Adrv9361z7035SignalSourceFPGA::get_right_block()
{ {
return {}; return {};
} }

View File

@ -1,7 +1,7 @@
/*! /*!
* \file ad9361_signal_source_fpga.h * \file adrv9361_z7035_signal_source_fpga.h
* \brief signal source for Analog Devices front-end AD9361 connected directly * \brief signal source for the Analog Devices ADRV9361-Z7035 evaluation board
* to FPGA accelerators. * directly connected to the FPGA accelerators.
* This source implements only the AD9361 control. It is NOT compatible with * This source implements only the AD9361 control. It is NOT compatible with
* conventional SDR acquisition and tracking blocks. * conventional SDR acquisition and tracking blocks.
* Please use the fmcomms2 source if conventional SDR acquisition and tracking * Please use the fmcomms2 source if conventional SDR acquisition and tracking
@ -12,14 +12,14 @@
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR. * This file is part of GNSS-SDR.
* *
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* ----------------------------------------------------------------------------- * -----------------------------------------------------------------------------
*/ */
#ifndef GNSS_SDR_AD9361_SIGNAL_SOURCE_FPGA_H #ifndef GNSS_SDR_ADRV9361_Z7035_SIGNAL_SOURCE_FPGA_H
#define GNSS_SDR_AD9361_SIGNAL_SOURCE_FPGA_H #define GNSS_SDR_ADRV9361_Z7035_SIGNAL_SOURCE_FPGA_H
#include "concurrent_queue.h" #include "concurrent_queue.h"
#include "fpga_buffer_monitor.h" #include "fpga_buffer_monitor.h"
@ -44,14 +44,14 @@
class ConfigurationInterface; class ConfigurationInterface;
class Ad9361SignalSourceFPGA : public SignalSourceBase class Adrv9361z7035SignalSourceFPGA : public SignalSourceBase
{ {
public: public:
Ad9361SignalSourceFPGA(const ConfigurationInterface *configuration, Adrv9361z7035SignalSourceFPGA(const ConfigurationInterface *configuration,
const std::string &role, unsigned int in_stream, const std::string &role, unsigned int in_stream,
unsigned int out_stream, Concurrent_Queue<pmt::pmt_t> *queue); unsigned int out_stream, Concurrent_Queue<pmt::pmt_t> *queue);
~Ad9361SignalSourceFPGA(); ~Adrv9361z7035SignalSourceFPGA();
inline size_t item_size() override inline size_t item_size() override
{ {
@ -139,4 +139,4 @@ private:
/** \} */ /** \} */
/** \} */ /** \} */
#endif // GNSS_SDR_AD9361_SIGNAL_SOURCE_FPGA_H #endif // GNSS_SDR_ADRV9361_Z7035_SIGNAL_SOURCE_FPGA_H

View File

@ -41,7 +41,7 @@ using namespace std::string_literals;
DMASignalSourceFPGA::DMASignalSourceFPGA(const ConfigurationInterface *configuration, DMASignalSourceFPGA::DMASignalSourceFPGA(const ConfigurationInterface *configuration,
const std::string &role, unsigned int in_stream, unsigned int out_stream, const std::string &role, unsigned int in_stream, unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused))) Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused)))
: SignalSourceBase(configuration, role, "DMA_Signal_Source_Fpga"s), : SignalSourceBase(configuration, role, "DMA_Signal_Source_FPGA"s),
queue_(queue), queue_(queue),
filename0_(configuration->property(role + ".filename", empty_string)), filename0_(configuration->property(role + ".filename", empty_string)),
sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)), sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)),

View File

@ -0,0 +1,347 @@
/*!
* \file fmcomms5_signal_source_fpga.cc
* \brief signal source for the Analog Devices FMCOMMS5 directly connected
* to the FPGA accelerators.
* This source implements only the AD9361 control. It is NOT compatible with
* conventional SDR acquisition and tracking blocks.
* Please use the fmcomms2 source if conventional SDR acquisition and tracking
* is selected in the configuration file.
* \authors <ul>
* <li> Javier Arribas, jarribas(at)cttc.es
* <li> Marc Majoral, mmajoral(at)cttc.es
* </ul>
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#include "fmcomms5_signal_source_fpga.h"
#include "GPS_L1_CA.h"
#include "GPS_L5.h"
#include "ad9361_manager.h"
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
#include "gnss_sdr_string_literals.h"
#include <algorithm> // for std::max
#include <chrono> // for std::chrono
#include <cmath> // for std::floor
#include <exception> // for std::exception
#include <iostream> // for std::cout
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h>
#else
#include <absl/log/check.h>
#include <absl/log/log.h>
#endif
using namespace std::string_literals;
Fmcomms5SignalSourceFPGA::Fmcomms5SignalSourceFPGA(const ConfigurationInterface *configuration,
const std::string &role, unsigned int in_stream, unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused)))
: SignalSourceBase(configuration, role, "FMCOMMS5_Signal_Source_FPGA"s),
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_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)),
filter_filename_(configuration->property(role + ".filter_filename", filter_file_)),
rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)),
rf_gain_rx2_(configuration->property(role + ".gain_rx2", default_manual_gain_rx2)),
freq0_(configuration->property(role + ".freq0", static_cast<uint64_t>(GPS_L1_FREQ_HZ))),
freq1_(configuration->property(role + ".freq1", static_cast<uint64_t>(GPS_L5_FREQ_HZ))),
sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)),
bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)),
Fpass_(configuration->property(role + ".Fpass", static_cast<float>(0.0))),
Fstop_(configuration->property(role + ".Fstop", static_cast<float>(0.0))),
in_stream_(in_stream),
out_stream_(out_stream),
item_size_(sizeof(int8_t)),
filter_auto_(configuration->property(role + ".filter_auto", false)),
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)),
enable_dynamic_bit_selection_(configuration->property(role + ".enable_dynamic_bit_selection", true)),
enable_ovf_check_buffer_monitor_active_(true),
dump_(configuration->property(role + ".dump", false)),
#if USE_GLOG_AND_GFLAGS
rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown))
#else
rf_shutdown_(configuration->property(role + ".rf_shutdown", absl::GetFlag(FLAGS_rf_shutdown)))
#endif
{
const bool enable_rx1_band((configuration->property("Channels_1C.count", 0) > 0) ||
(configuration->property("Channels_1B.count", 0) > 0));
const bool enable_rx2_band((configuration->property("Channels_L2.count", 0) > 0) ||
(configuration->property("Channels_L5.count", 0) > 0) ||
(configuration->property("Channels_5X.count", 0) > 0));
const uint32_t num_freq_bands = ((enable_rx1_band == true) and (enable_rx2_band == true)) ? 2 : 1;
if (filter_auto_)
{
filter_source_ = configuration->property(role + ".filter_source", std::string("Auto"));
}
else
{
filter_source_ = configuration->property(role + ".filter_source", std::string("Off"));
}
switch_fpga = std::make_shared<Fpga_Switch>();
switch_fpga->set_switch_position(switch_to_real_time_mode);
std::cout << "Sample rate: " << sample_rate_ << " Sps\n";
// some basic checks
if ((rf_port_select_ != "A_BALANCED") && (rf_port_select_ != "B_BALANCED") && (rf_port_select_ != "A_N") && (rf_port_select_ != "B_N") && (rf_port_select_ != "B_P") && (rf_port_select_ != "C_N") && (rf_port_select_ != "C_P") && (rf_port_select_ != "TX_MONITOR1") && (rf_port_select_ != "TX_MONITOR2") && (rf_port_select_ != "TX_MONITOR1_2"))
{
std::cout << "Configuration parameter rf_port_select should take one of these values:\n";
std::cout << " A_BALANCED, B_BALANCED, A_N, B_N, B_P, C_N, C_P, TX_MONITOR1, TX_MONITOR2, TX_MONITOR1_2\n";
std::cout << "Error: provided value rf_port_select=" << rf_port_select_ << " is not among valid values\n";
std::cout << " This parameter has been set to its default value rf_port_select=" << default_rf_port_select << '\n';
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") && (gain_mode_rx1_ != "slow_attack") && (gain_mode_rx1_ != "fast_attack") && (gain_mode_rx1_ != "hybrid"))
{
std::cout << "Configuration parameter gain_mode_rx1 should take one of these values:\n";
std::cout << " manual, slow_attack, fast_attack, hybrid\n";
std::cout << "Error: provided value gain_mode_rx1=" << gain_mode_rx1_ << " is not among valid values\n";
std::cout << " This parameter has been set to its default value gain_mode_rx1=" << default_gain_mode << '\n';
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") && (gain_mode_rx2_ != "slow_attack") && (gain_mode_rx2_ != "fast_attack") && (gain_mode_rx2_ != "hybrid"))
{
std::cout << "Configuration parameter gain_mode_rx2 should take one of these values:\n";
std::cout << " manual, slow_attack, fast_attack, hybrid\n";
std::cout << "Error: provided value gain_mode_rx2=" << gain_mode_rx2_ << " is not among valid values\n";
std::cout << " This parameter has been set to its default value gain_mode_rx2=" << default_gain_mode << '\n';
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 || rf_gain_rx1_ < -1.0)
{
std::cout << "Configuration parameter rf_gain_rx1 should take values between -1.0 and 73 dB\n";
std::cout << "Error: provided value rf_gain_rx1=" << rf_gain_rx1_ << " is not among valid values\n";
std::cout << " This parameter has been set to its default value rf_gain_rx1=" << default_manual_gain_rx1 << '\n';
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 || rf_gain_rx2_ < -1.0)
{
std::cout << "Configuration parameter rf_gain_rx2 should take values between -1.0 and 73 dB\n";
std::cout << "Error: provided value rf_gain_rx2=" << rf_gain_rx2_ << " is not among valid values\n";
std::cout << " This parameter has been set to its default value rf_gain_rx2=" << default_manual_gain_rx2 << '\n';
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;
}
}
if ((filter_source_ != "Off") && (filter_source_ != "Auto") && (filter_source_ != "File") && (filter_source_ != "Design"))
{
std::cout << "Configuration parameter filter_source should take one of these values:\n";
std::cout << " Off: Disable filter\n";
std::cout << " Auto: Use auto-generated filters\n";
std::cout << " File: User-provided filter in filter_filename parameter\n";
std::cout << " Design: Create filter from Fpass, Fstop, sampling_frequency and bandwidth parameters\n";
std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values\n";
std::cout << " This parameter has been set to its default value filter_source=Off\n";
filter_source_ = std::string("Off");
LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off";
}
if (bandwidth_ < 200000 || bandwidth_ > 56000000)
{
std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz\n";
std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values\n";
std::cout << " This parameter has been set to its default value bandwidth=" << default_bandwidth << '\n';
bandwidth_ = default_bandwidth;
LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=" << default_bandwidth;
}
if (enable_rx1_band)
{
std::cout << "LO 0 frequency : " << freq0_ << " Hz\n";
}
if (enable_rx2_band)
{
std::cout << "LO 1 frequency : " << freq1_ << " Hz\n";
}
try
{
config_ad9361_rx_local(bandwidth_,
sample_rate_,
freq0_,
freq1_,
rf_port_select_,
rx1_enable_,
rx2_enable_,
gain_mode_rx1_,
gain_mode_rx2_,
rf_gain_rx1_,
rf_gain_rx2_,
quadrature_,
rf_dc_,
bb_dc_,
filter_source_,
filter_filename_,
Fpass_,
Fstop_);
}
catch (const std::runtime_error &e)
{
std::cerr << "Exception cached when configuring the RX chain: " << e.what() << '\n';
return;
}
std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename);
buffer_monitor_fpga = std::make_shared<Fpga_buffer_monitor>(num_freq_bands, dump_, dump_filename);
thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); });
// dynamic bits selection
if (enable_dynamic_bit_selection_)
{
dynamic_bit_selection_fpga = std::make_shared<Fpga_dynamic_bit_selection>(enable_rx1_band, enable_rx2_band);
thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); });
}
if (in_stream_ > 0)
{
LOG(ERROR) << "A signal source does not have an input stream";
}
if (out_stream_ > 1)
{
LOG(ERROR) << "This implementation only supports one output stream";
}
}
Fmcomms5SignalSourceFPGA::~Fmcomms5SignalSourceFPGA()
{
/* cleanup and exit */
if (rf_shutdown_)
{
std::cout << "* Disabling RX streaming channels\n";
if (!disable_ad9361_rx_local())
{
LOG(WARNING) << "Problem shutting down the AD9361 RX channels";
}
}
// disable buffer overflow checking and buffer monitoring
std::unique_lock<std::mutex> lock_buffer_monitor(buffer_monitor_mutex);
enable_ovf_check_buffer_monitor_active_ = false;
lock_buffer_monitor.unlock();
if (thread_buffer_monitor.joinable())
{
thread_buffer_monitor.join();
}
std::unique_lock<std::mutex> lock_dyn_bit_sel(dynamic_bit_selection_mutex);
bool bit_selection_enabled = enable_dynamic_bit_selection_;
lock_dyn_bit_sel.unlock();
if (bit_selection_enabled == true)
{
std::unique_lock<std::mutex> lock(dynamic_bit_selection_mutex);
enable_dynamic_bit_selection_ = false;
lock.unlock();
if (thread_dynamic_bit_selection.joinable())
{
thread_dynamic_bit_selection.join();
}
}
}
void Fmcomms5SignalSourceFPGA::run_dynamic_bit_selection_process()
{
bool dynamic_bit_selection_active = true;
while (dynamic_bit_selection_active)
{
// setting the bit selection to the top bits
dynamic_bit_selection_fpga->bit_selection();
std::this_thread::sleep_for(std::chrono::milliseconds(Gain_control_period_ms));
std::unique_lock<std::mutex> lock(dynamic_bit_selection_mutex);
if (enable_dynamic_bit_selection_ == false)
{
dynamic_bit_selection_active = false;
}
lock.unlock();
}
}
void Fmcomms5SignalSourceFPGA::run_buffer_monitor_process()
{
bool enable_ovf_check_buffer_monitor_active = true;
std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitoring_initial_delay_ms));
while (enable_ovf_check_buffer_monitor_active)
{
buffer_monitor_fpga->check_buffer_overflow_and_monitor_buffer_status();
std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitor_period_ms));
std::unique_lock<std::mutex> lock(buffer_monitor_mutex);
if (enable_ovf_check_buffer_monitor_active_ == false)
{
enable_ovf_check_buffer_monitor_active = false;
}
lock.unlock();
}
}
void Fmcomms5SignalSourceFPGA::connect(gr::top_block_sptr top_block)
{
if (top_block)
{ /* top_block is not null */
};
DLOG(INFO) << "AD9361 FPGA source nothing to connect";
}
void Fmcomms5SignalSourceFPGA::disconnect(gr::top_block_sptr top_block)
{
if (top_block)
{ /* top_block is not null */
};
DLOG(INFO) << "AD9361 FPGA source nothing to disconnect";
}
gr::basic_block_sptr Fmcomms5SignalSourceFPGA::get_left_block()
{
LOG(WARNING) << "Trying to get signal source left block.";
return {};
}
gr::basic_block_sptr Fmcomms5SignalSourceFPGA::get_right_block()
{
return {};
}

View File

@ -0,0 +1,135 @@
/*!
* \file fmcomms5_signal_source_fpga.h
* \brief signal source for the Analog Devices FMCOMMS5 directly connected
* to the FPGA accelerators.
* This source implements only the AD9361 control. It is NOT compatible with
* conventional SDR acquisition and tracking blocks.
* Please use the fmcomms2 source if conventional SDR acquisition and tracking
* is selected in the configuration file.
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_FMCOMMS5_SIGNAL_SOURCE_FPGA_H
#define GNSS_SDR_FMCOMMS5_SIGNAL_SOURCE_FPGA_H
#include "concurrent_queue.h"
#include "fpga_buffer_monitor.h"
#include "fpga_dma-proxy.h"
#include "fpga_dynamic_bit_selection.h"
#include "fpga_switch.h"
#include "gnss_block_interface.h"
#include "signal_source_base.h"
#include <pmt/pmt.h>
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
/** \addtogroup Signal_Source
* \{ */
/** \addtogroup Signal_Source_adapters
* \{ */
class ConfigurationInterface;
class Fmcomms5SignalSourceFPGA : public SignalSourceBase
{
public:
Fmcomms5SignalSourceFPGA(const ConfigurationInterface *configuration,
const std::string &role, unsigned int in_stream,
unsigned int out_stream, Concurrent_Queue<pmt::pmt_t> *queue);
~Fmcomms5SignalSourceFPGA();
inline size_t item_size() override
{
return item_size_;
}
void connect(gr::top_block_sptr top_block) override;
void disconnect(gr::top_block_sptr top_block) override;
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_right_block() override;
private:
const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat");
const std::string default_rf_port_select = std::string("A_BALANCED");
const std::string default_gain_mode = std::string("slow_attack");
const double default_tx_attenuation_db = -10.0;
const double default_manual_gain_rx1 = 64.0;
const double default_manual_gain_rx2 = 64.0;
const uint64_t default_bandwidth = 12500000;
// perform dynamic bit selection every 500 ms by default
const uint32_t Gain_control_period_ms = 500;
// check buffer overflow and perform buffer monitoring every 1s by default
const uint32_t buffer_monitor_period_ms = 1000;
// buffer overflow and buffer monitoring initial delay
const uint32_t buffer_monitoring_initial_delay_ms = 2000;
// sample block size when running in post-processing mode
const int sample_block_size = 16384;
const int32_t switch_to_real_time_mode = 2;
void run_dynamic_bit_selection_process();
void run_buffer_monitor_process();
std::thread thread_dynamic_bit_selection;
std::thread thread_buffer_monitor;
std::shared_ptr<Fpga_Switch> switch_fpga;
std::shared_ptr<Fpga_dynamic_bit_selection> dynamic_bit_selection_fpga;
std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga;
std::mutex dynamic_bit_selection_mutex;
std::mutex buffer_monitor_mutex;
std::string gain_mode_rx1_;
std::string gain_mode_rx2_;
std::string rf_port_select_;
std::string filter_file_;
std::string filter_source_;
std::string filter_filename_;
double rf_gain_rx1_;
double rf_gain_rx2_;
uint64_t freq0_; // frequency of local oscillator for ADRV9361-A
uint64_t freq1_; // frequency of local oscillator for ADRV9361-B
uint64_t sample_rate_;
uint64_t bandwidth_;
float Fpass_;
float Fstop_;
uint32_t in_stream_;
uint32_t out_stream_;
size_t item_size_;
bool filter_auto_;
bool quadrature_;
bool rf_dc_;
bool bb_dc_;
bool rx1_enable_;
bool rx2_enable_;
bool enable_dynamic_bit_selection_;
bool enable_ovf_check_buffer_monitor_active_;
bool dump_;
bool rf_shutdown_;
};
/** \} */
/** \} */
#endif // GNSS_SDR_FMCOMMS5_SIGNAL_SOURCE_FPGA_H

View File

@ -40,7 +40,7 @@ using namespace std::string_literals;
MAX2771EVKITSignalSourceFPGA::MAX2771EVKITSignalSourceFPGA(const ConfigurationInterface *configuration, MAX2771EVKITSignalSourceFPGA::MAX2771EVKITSignalSourceFPGA(const ConfigurationInterface *configuration,
const std::string &role, unsigned int in_stream, unsigned int out_stream, const std::string &role, unsigned int in_stream, unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused))) Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused)))
: SignalSourceBase(configuration, role, "MAX2771_EVKIT_Signal_Source_Fpga"s), : SignalSourceBase(configuration, role, "MAX2771_EVKIT_Signal_Source_FPGA"s),
freq_(configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ))), freq_(configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ))),
sample_rate_(configuration->property(role + ".sampling_frequency", default_sampling_rate)), sample_rate_(configuration->property(role + ".sampling_frequency", default_sampling_rate)),
in_stream_(in_stream), in_stream_(in_stream),

View File

@ -166,8 +166,9 @@
#include "fmcomms2_signal_source.h" #include "fmcomms2_signal_source.h"
#endif #endif
#if AD9361_DRIVER #if ENABLE_FPGA and AD9361_DRIVER
#include "ad9361_signal_source_fpga.h" #include "adrv9361_z7035_signal_source_fpga.h"
#include "fmcomms5_signal_source_fpga.h"
#endif #endif
#if MAX2771_DRIVER #if MAX2771_DRIVER
@ -820,16 +821,22 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
#endif #endif
#if ENABLE_FPGA and AD9361_DRIVER #if ENABLE_FPGA and AD9361_DRIVER
else if (implementation == "Ad9361_Signal_Source_Fpga") else if (implementation == "Adrv9361_Z7035_Signal_Source_Fpga")
{ {
std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<Ad9361SignalSourceFPGA>(configuration, role, in_streams, std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<Adrv9361z7035SignalSourceFPGA>(configuration, role, in_streams,
out_streams, queue);
block = std::move(block_);
}
else if (implementation == "Fmcomms5_Signal_Source_Fpga")
{
std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<Fmcomms5SignalSourceFPGA>(configuration, role, in_streams,
out_streams, queue); out_streams, queue);
block = std::move(block_); block = std::move(block_);
} }
#endif #endif
#if ENABLE_FPGA and MAX2771_DRIVER #if ENABLE_FPGA and MAX2771_DRIVER
else if (implementation == "MAX2771_EVKIT_Signal_Source_Fpga") else if (implementation == "Max2771_Evkit_Signal_Source_Fpga")
{ {
std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<MAX2771EVKITSignalSourceFPGA>(configuration, role, in_streams, std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<MAX2771EVKITSignalSourceFPGA>(configuration, role, in_streams,
out_streams, queue); out_streams, queue);
@ -838,7 +845,7 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
#endif #endif
#if ENABLE_FPGA and DMA_PROXY_DRIVER #if ENABLE_FPGA and DMA_PROXY_DRIVER
else if (implementation == "DMA_Signal_Source_Fpga") else if (implementation == "Dma_Signal_Source_Fpga")
{ {
std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<DMASignalSourceFPGA>(configuration, role, in_streams, std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<DMASignalSourceFPGA>(configuration, role, in_streams,
out_streams, queue); out_streams, queue);