mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-11-10 20:10:05 +00:00
Add the MAX2771_EVKIT FPGA signal source and the ENABLE_FPGA_MAX2771_EVKIT flag to enable it.
This commit is contained in:
parent
ac7bdc919b
commit
d24c35854a
@ -44,6 +44,8 @@ option(ENABLE_AD936X_SDR "Enable the use of AD936X front-ends using libiio, requ
|
||||
|
||||
option(ENABLE_AD9361 "Enable the use of AD9361 direct to FPGA hardware, requires libiio" OFF)
|
||||
|
||||
option(ENABLE_FPGA_MAX2771_EVKIT "Enable the use of MAX2771 EVKIT direct to FPGA hardware" OFF)
|
||||
|
||||
option(ENABLE_RAW_UDP "Enable the use of high-optimized custom UDP packet sample source, requires libpcap" OFF)
|
||||
|
||||
option(ENABLE_FLEXIBAND "Enable the use of the signal source adater for the Teleorbit Flexiband GNU Radio driver" OFF)
|
||||
@ -3552,6 +3554,7 @@ add_feature_info(ENABLE_LIMESDR ENABLE_LIMESDR "Enables Limesdr_Signal_Source. R
|
||||
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-dev.")
|
||||
add_feature_info(ENABLE_FPGA_MAX2771_EVKIT ENABLE_FPGA_MAX2771_EVKIT "Enables MAX2771_evkit_fpga_signal_source for devices with the MAX2771 chipset.")
|
||||
add_feature_info(ENABLE_AD936X_SDR ENABLE_AD936X_SDR "Enables Ad936x_Iio_Signal_Source to access AD936X front-ends using libiio. 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.")
|
||||
|
@ -41,6 +41,14 @@ if(ENABLE_AD9361)
|
||||
list(APPEND OPT_DRIVER_HEADERS ad9361_fpga_signal_source.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FPGA_MAX2771_EVKIT)
|
||||
###############################################
|
||||
# MAX2771 EVKIT DIRECT TO FPGA Hardware
|
||||
###############################################
|
||||
list(APPEND OPT_DRIVER_SOURCES max2771_evkit_fpga_signal_source.cc)
|
||||
list(APPEND OPT_DRIVER_HEADERS max2771_evkit_fpga_signal_source.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FPGA)
|
||||
###############################################
|
||||
# FPGA DMA source
|
||||
@ -159,7 +167,7 @@ target_include_directories(signal_source_adapters
|
||||
${GNSSSDR_SOURCE_DIR}/src/core/interfaces
|
||||
)
|
||||
|
||||
if(ENABLE_FPGA OR ENABLE_AD9361)
|
||||
if(ENABLE_FPGA OR ENABLE_AD9361 OR ENABLE_FPGA_MAX2771_EVKIT)
|
||||
target_link_libraries(signal_source_adapters
|
||||
PUBLIC
|
||||
signal_source_libs
|
||||
|
@ -0,0 +1,468 @@
|
||||
/*!
|
||||
* \file max2771_evkit_fpga_signal_source.cc
|
||||
* \brief Signal source for the MAX2771EVKIT evaluation board connected directly
|
||||
* to FPGA accelerators.
|
||||
* This source implements only the MAX2771 control. It is NOT compatible with
|
||||
* conventional SDR acquisition and tracking blocks.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* 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 "max2771_evkit_fpga_signal_source.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "GPS_L2C.h"
|
||||
#include "GPS_L5.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;
|
||||
|
||||
MAX2771EVKITFpgaSignalSource::MAX2771EVKITFpgaSignalSource(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, "Ad9361_Fpga_Signal_Source"s),
|
||||
freq_(configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ))),
|
||||
sample_rate_(configuration->property(role + ".sampling_frequency", default_sampling_rate)),
|
||||
in_stream_(in_stream),
|
||||
out_stream_(out_stream),
|
||||
bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)),
|
||||
filter_order_(configuration->property(role + ".filter_order", default_filter_order)),
|
||||
gain_in_(configuration->property(role + ".PGA_gain", default_PGA_gain_value)),
|
||||
item_size_(sizeof(int8_t)),
|
||||
chipen_(true),
|
||||
if_filter_gain_(configuration->property(role + ".enable_IF_filter_gain", true)),
|
||||
LNA_active_(configuration->property(role + ".LNA_active", false)),
|
||||
enable_agc_(configuration->property(role + ".enable_AGC", 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
|
||||
{
|
||||
// some basic checks
|
||||
if (freq_ != GPS_L1_FREQ_HZ and freq_ != GPS_L2_FREQ_HZ and freq_ != GPS_L5_FREQ_HZ)
|
||||
{
|
||||
std::cout << "Configuration parameter freq should take values " << GPS_L1_FREQ_HZ << ", " << GPS_L2_FREQ_HZ << ", or " << GPS_L5_FREQ_HZ << "\n";
|
||||
std::cout << "Error: provided value freq = " << freq_ << " is not among valid values\n";
|
||||
std::cout << " This parameter has been set to its default value freq = " << GPS_L1_FREQ_HZ << '\n';
|
||||
LOG(WARNING) << "Invalid configuration value for freq parameter. Set to freq = " << GPS_L1_FREQ_HZ;
|
||||
freq_ = GPS_L1_FREQ_HZ;
|
||||
}
|
||||
if (sample_rate_ != 4092000 and sample_rate_ != 8184000 and sample_rate_ != 16368000 and sample_rate_ != 32736000)
|
||||
{
|
||||
std::cout << "Configuration parameter sampling_frequency should take values 4092000, 8184000, 16368000, or 32736000\n";
|
||||
std::cout << "Error: provided value sampling_frequency = " << sample_rate_ << " is not among valid values\n";
|
||||
std::cout << " This parameter has been set to its default value sampling_frequency = " << default_sampling_rate << '\n';
|
||||
LOG(WARNING) << "Invalid configuration value for sampling_frequency parameter. Set to sampling_frequency = " << default_sampling_rate;
|
||||
sample_rate_ = default_sampling_rate;
|
||||
}
|
||||
if (bandwidth_ != 2500000 and bandwidth_ != 4200000 and bandwidth_ != 8700000 and bandwidth_ != 16400000 and bandwidth_ != 23400000 and bandwidth_ != 36000000)
|
||||
{
|
||||
std::cout << "Configuration parameter bandwidth can only take the following values: 2500000, 4200000, 8700000, 16400000, 23400000, and 36000000 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';
|
||||
LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth = " << default_bandwidth;
|
||||
bandwidth_ = default_bandwidth;
|
||||
}
|
||||
if (filter_order_ != 3 and filter_order_ != 5)
|
||||
{
|
||||
std::cout << "Configuration parameter filter_order should take values 3 or 5\n";
|
||||
std::cout << "Error: provided value filter_order = " << filter_order_ << " is not among valid values\n";
|
||||
std::cout << " This parameter has been set to its default value filter_order = " << default_filter_order << '\n';
|
||||
LOG(WARNING) << "Invalid configuration value for filter_order parameter. Set to filter_order = " << default_filter_order;
|
||||
filter_order_ = default_filter_order;
|
||||
}
|
||||
if (gain_in_ > max_PGA_gain_value)
|
||||
{
|
||||
std::cout << "Configuration parameter PGA_gain should be up to " << max_PGA_gain_value << "\n";
|
||||
std::cout << "Error: provided value PGA_gain = " << gain_in_ << " is not among valid values\n";
|
||||
std::cout << " This parameter has been set to its default value PGA_gain = " << default_PGA_gain_value << '\n';
|
||||
LOG(WARNING) << "Invalid configuration value for PGA_gain parameter. Set to PGA_gain = " << default_PGA_gain_value;
|
||||
gain_in_ = default_PGA_gain_value;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> register_values = setup_regs();
|
||||
|
||||
spidev_fpga = std::make_shared<Fpga_spidev>();
|
||||
|
||||
if (spidev_fpga->SPI_open())
|
||||
{
|
||||
std::cerr << "Cannot open SPI device\n";
|
||||
// stop the receiver
|
||||
queue->push(pmt::make_any(command_event_make(200, 0)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (configure(register_values))
|
||||
{
|
||||
std::cerr << "Error configuring the MAX2771 device " << '\n';
|
||||
}
|
||||
|
||||
if (spidev_fpga->SPI_close())
|
||||
{
|
||||
std::cerr << "Error closing SPI device " << '\n';
|
||||
}
|
||||
|
||||
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(); });
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint32_t> MAX2771EVKITFpgaSignalSource::setup_regs(void)
|
||||
{
|
||||
std::vector<uint32_t> register_values = std::vector<uint32_t>(MAX2771_NUM_REGS);
|
||||
|
||||
|
||||
uint32_t LNA_mode = (LNA_active_) ? 0x0 : 0x2;
|
||||
|
||||
uint32_t Filter_Bandwidth;
|
||||
|
||||
switch (bandwidth_)
|
||||
{
|
||||
case 2500000:
|
||||
Filter_Bandwidth = 0x0;
|
||||
break;
|
||||
case 4200000:
|
||||
Filter_Bandwidth = 0x2;
|
||||
break;
|
||||
case 8700000:
|
||||
Filter_Bandwidth = 0x1;
|
||||
break;
|
||||
case 16400000:
|
||||
Filter_Bandwidth = 0x7;
|
||||
break;
|
||||
case 23400000:
|
||||
Filter_Bandwidth = 0x3;
|
||||
break;
|
||||
case 36000000:
|
||||
Filter_Bandwidth = 0x4;
|
||||
break;
|
||||
default:
|
||||
Filter_Bandwidth = 0x0; // default bandwidth
|
||||
}
|
||||
|
||||
uint32_t chipen_select = (chipen_) ? 0x1 : 0x0;
|
||||
uint32_t Filter_order_sel = (filter_order_ == 5) ? 0x0 : 0x1;
|
||||
uint32_t IF_filter_gain_sel = (if_filter_gain_) ? 0x1 : 0x0;
|
||||
|
||||
register_values[0] = // configuration 1 register
|
||||
(chipen_select << 31) +
|
||||
(IDLE << 30) +
|
||||
(0x8 << 26) + // reserved
|
||||
(0x8 << 22) + // reserved
|
||||
(0x2 << 20) + // reserved
|
||||
(0x1 << 18) + // reserved
|
||||
(MIXPOLE << 17) +
|
||||
(LNA_mode << 15) +
|
||||
(MIXERMODE << 13) +
|
||||
(FCEN << 6) +
|
||||
(Filter_Bandwidth << 3) +
|
||||
(Filter_order_sel << 2) +
|
||||
(FCENX << 1) +
|
||||
IF_filter_gain_sel;
|
||||
|
||||
uint32_t AGC_mode = (enable_agc_) ? 0x0 : 0x2;
|
||||
|
||||
register_values[1] = // configuration 2 register
|
||||
(0x0 << 31) + // reserved
|
||||
(0x1 << 29) + // reserved
|
||||
(ANAIMON << 28) +
|
||||
(IQEN << 27) +
|
||||
(GAINREF << 15) +
|
||||
(SPI_SDIO_CONFIG << 13) +
|
||||
(AGC_mode << 11) +
|
||||
(FORMAT << 9) +
|
||||
(BITS << 6) +
|
||||
(DRVCFG << 4) +
|
||||
(0x1 << 3) + // reserved
|
||||
(0x0 << 2) + // reserved
|
||||
DIEID;
|
||||
|
||||
register_values[2] = // configuration 3 register
|
||||
(0x0 << 28) + //reserved
|
||||
(gain_in_ << 22) +
|
||||
(0x1 << 21) + // reserved
|
||||
(HILOADEN << 20) +
|
||||
(0x1 << 19) + // reserved
|
||||
(0x1 << 18) + // reserved
|
||||
(0x1 << 17) + // reserved
|
||||
(0x1 << 16) + // reserved
|
||||
(FHIPEN << 15) +
|
||||
(0x0 << 14) + // reserved
|
||||
(PGAIEN << 13) +
|
||||
(PGAQEN << 12) +
|
||||
(STRMEN << 11) +
|
||||
(STRMSTART << 10) +
|
||||
(STRMSTOP << 9) +
|
||||
(0x7 << 6) + // reserved
|
||||
(STRMBITS << 4) +
|
||||
(STAMPEN << 3) +
|
||||
(TIMESYNCEN << 2) +
|
||||
(DATASYNCEN << 1) +
|
||||
STRMRST;
|
||||
|
||||
uint32_t clock_out_div_ratio;
|
||||
|
||||
switch (sample_rate_)
|
||||
{
|
||||
case 4092000:
|
||||
clock_out_div_ratio = 0x1; // XTAL frequency /4
|
||||
break;
|
||||
case 8184000:
|
||||
clock_out_div_ratio = 0x2; // XTAL frequency /2
|
||||
break;
|
||||
case 16368000:
|
||||
clock_out_div_ratio = 0x3; // XTAL frequency
|
||||
break;
|
||||
case 32736000:
|
||||
clock_out_div_ratio = 0x0; // XTAL Frequency x2
|
||||
break;
|
||||
default:
|
||||
clock_out_div_ratio = 0x1; // default XTAL frequency
|
||||
}
|
||||
|
||||
register_values[3] = // PLL configuration register
|
||||
(clock_out_div_ratio << 29) +
|
||||
(LOBAND << 28) +
|
||||
(0x1 << 27) + // reserved
|
||||
(0x0 << 26) + // reserved
|
||||
(0x0 << 25) + // reserved
|
||||
(REFOUTEN << 24) +
|
||||
(0x1 << 23) + // reserved
|
||||
(0x0 << 21) + // reserved
|
||||
(IXTAL << 19) +
|
||||
(0x10 << 14) + // reserved
|
||||
(0x0 << 13) + // reserved
|
||||
(0x0 << 10) + //reserved
|
||||
(ICP << 9) +
|
||||
(0x0 << 8) + // reserved
|
||||
(0x0 << 7) + // reserved
|
||||
(0x0 << 4) + // reserved
|
||||
(INT_PLL << 3) +
|
||||
(PWRSAV << 2) +
|
||||
(0x0 << 1) + // reserved
|
||||
0x0; // reserved
|
||||
|
||||
uint32_t freq_sel;
|
||||
switch (freq_)
|
||||
{
|
||||
case static_cast<uint64_t>(GPS_L1_FREQ_HZ):
|
||||
freq_sel = 0x604;
|
||||
break;
|
||||
case static_cast<uint64_t>(GPS_L2_FREQ_HZ):
|
||||
freq_sel = 0x4B0;
|
||||
break;
|
||||
case static_cast<uint64_t>(GPS_L5_FREQ_HZ):
|
||||
freq_sel = 0x47E;
|
||||
break;
|
||||
default:
|
||||
freq_sel = 0x604;
|
||||
}
|
||||
//uint32_t freq_sel = (freq_ == GPS_L1_FREQ_HZ) ? 0x604 :
|
||||
register_values[4] = // PLL integer division register
|
||||
(0x0 << 28) + //reserved
|
||||
(freq_sel << 13) +
|
||||
(RDIV << 3) +
|
||||
0x0; // reserved
|
||||
|
||||
register_values[5] = // PLL fractional division register
|
||||
(0x0 << 28) + // reserved
|
||||
(FDIV << 8) +
|
||||
(0x7 << 4) + // reserved
|
||||
(0x0 << 3) + // reserved
|
||||
(0x0 << 2) + // reserved
|
||||
(0x0 << 1) + // reserved
|
||||
0x0; // reserved
|
||||
|
||||
register_values[6] = // DSP interface register
|
||||
(0x0 << 28) + // reserved
|
||||
0x8000000; // reserved
|
||||
|
||||
register_values[7] = // clock configuration 1 register
|
||||
(0x0 << 29) + // reserved
|
||||
(EXTADCCLK << 28) +
|
||||
(REFCLK_L_CNT << 16) +
|
||||
(REFCLK_M_CNT << 4) +
|
||||
(FCLKIN << 3) +
|
||||
(ADCCLK << 2) +
|
||||
(0x1 << 1) + //reserved
|
||||
MODE;
|
||||
|
||||
register_values[8] = TEST_MODE_1_REG_VAL; // test mode 1 register
|
||||
|
||||
register_values[9] = TEST_MODE_2_REG_VAL; // test mode 2 register
|
||||
|
||||
register_values[10] = // clock configuration 2 register
|
||||
(0x0 << 29) + // reserved
|
||||
(0x0 << 28) + // reserved
|
||||
(ADCCLK_L_CNT << 16) +
|
||||
(ADCCLK_M_CNT << 4) +
|
||||
(PRE_FRACDIV_SEL << 3) +
|
||||
(CLKOUT_SEL << 2) +
|
||||
0x0; // reserved
|
||||
|
||||
return register_values;
|
||||
}
|
||||
|
||||
|
||||
bool MAX2771EVKITFpgaSignalSource::configure(std::vector<uint32_t> register_values)
|
||||
{
|
||||
// write the registers
|
||||
std::cerr << "Configuring MAX2771 registers" << std::endl;
|
||||
uint32_t status = 0;
|
||||
for (uint32_t k = 0; k < register_values.size(); k++)
|
||||
{
|
||||
status = spidev_fpga->write_reg32(k, register_values[k]);
|
||||
if (status)
|
||||
{
|
||||
std::cerr << "Error writing the MAX2771 registers" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Read the registers and verify that the values are correctly written
|
||||
std::vector<uint32_t> reg_read = std::vector<uint32_t>(register_values.size());
|
||||
|
||||
for (uint8_t n = 0; n < register_values.size(); ++n)
|
||||
{
|
||||
status = spidev_fpga->read_reg32(n, ®_read[n]);
|
||||
if (status)
|
||||
{
|
||||
std::cerr << "Error reading the MAX2771 registers" << std::endl;
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reg_read[n] != register_values[n])
|
||||
{
|
||||
std::cerr << "Error: Failed to verify the MAX2771 registers " << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MAX2771EVKITFpgaSignalSource::~MAX2771EVKITFpgaSignalSource()
|
||||
{
|
||||
/* cleanup and exit */
|
||||
|
||||
if (rf_shutdown_)
|
||||
{
|
||||
chipen_ = false;
|
||||
std::cout << "* MAX2771 Disabling RX streaming channels\n";
|
||||
std::vector<uint32_t> register_values = setup_regs();
|
||||
|
||||
if (spidev_fpga->SPI_open())
|
||||
{
|
||||
std::cerr << "Cannot open SPI device\n";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (configure(register_values))
|
||||
{
|
||||
std::cerr << "Error disabling the MAX2771 device " << '\n';
|
||||
}
|
||||
|
||||
if (spidev_fpga->SPI_close())
|
||||
{
|
||||
std::cerr << "Error closing SPI device " << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MAX2771EVKITFpgaSignalSource::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 MAX2771EVKITFpgaSignalSource::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (top_block)
|
||||
{ /* top_block is not null */
|
||||
};
|
||||
DLOG(INFO) << "AD9361 FPGA source nothing to connect";
|
||||
}
|
||||
|
||||
|
||||
void MAX2771EVKITFpgaSignalSource::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 MAX2771EVKITFpgaSignalSource::get_left_block()
|
||||
{
|
||||
LOG(WARNING) << "Trying to get signal source left block.";
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr MAX2771EVKITFpgaSignalSource::get_right_block()
|
||||
{
|
||||
return {};
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
/*!
|
||||
* \file max2771_evkit_fpga_signal_source.h
|
||||
* \brief Signal source for the MAX2771EVKIT evaluation board connected directly
|
||||
* to FPGA accelerators.
|
||||
* This source implements only the MAX2771 control. It is NOT compatible with
|
||||
* conventional SDR acquisition and tracking blocks.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* 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_MAX2771_EVKIT_FPGA_SIGNAL_SOURCE_H
|
||||
#define GNSS_SDR_MAX2771_EVKIT_FPGA_SIGNAL_SOURCE_H
|
||||
|
||||
#include "command_event.h"
|
||||
#include "concurrent_queue.h"
|
||||
#include "fpga_buffer_monitor.h"
|
||||
#include "fpga_spidev.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "signal_source_base.h"
|
||||
#include <pmt/pmt.h> // for pmt::pmt_t
|
||||
#include <cstdint> // for fixed-width integer types
|
||||
#include <memory> // for smart pointers
|
||||
#include <mutex> // for mutex
|
||||
#include <string> // for strings
|
||||
#include <thread> // for threads
|
||||
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
* \{ */
|
||||
/** \addtogroup Signal_Source_adapters
|
||||
* \{ */
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
class MAX2771EVKITFpgaSignalSource : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
MAX2771EVKITFpgaSignalSource(const ConfigurationInterface *configuration,
|
||||
const std::string &role, unsigned int in_stream,
|
||||
unsigned int out_stream, Concurrent_Queue<pmt::pmt_t> *queue);
|
||||
|
||||
~MAX2771EVKITFpgaSignalSource();
|
||||
|
||||
std::vector<uint32_t> setup_regs(void);
|
||||
|
||||
|
||||
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 uint64_t default_bandwidth = 2500000;
|
||||
const uint32_t default_filter_order = 5;
|
||||
const uint64_t default_sampling_rate = 4092000;
|
||||
const uint32_t default_PGA_gain_value = 0x3A; // default PGA gain when AGC is off
|
||||
// max PGA gain value
|
||||
const uint32_t max_PGA_gain_value = 0x3F;
|
||||
// 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;
|
||||
// MAX2771 number of configuration registers
|
||||
const uint32_t MAX2771_NUM_REGS = 11;
|
||||
// MAX2771 configuration register fields
|
||||
const uint32_t NUM_FREQ_BANDS = 1;
|
||||
const uint32_t IDLE = 0x0; // Idle mode disabled
|
||||
const uint32_t MIXPOLE = 0x0; // set the passive filter pole at mixer output at 13 MHz.
|
||||
const uint32_t MIXERMODE = 0x0; // L1 band enabled
|
||||
const uint32_t FCEN = 0x58; // Center frequency not used when in low-pass filter mode. Set to default value.
|
||||
const uint32_t FCENX = 0x0; // POlyphase filter selection set to Lowpass filter
|
||||
const uint32_t ANAIMON = 0x0; // analog monitor disabled
|
||||
const uint32_t IQEN = 0x1; // I and Q channels enable
|
||||
const uint32_t GAINREF = 0xAA; // AGC Gain ref
|
||||
const uint32_t SPI_SDIO_CONFIG = 0x0; // SPI SDIO config when tri-stated: nothing applied
|
||||
const uint32_t FORMAT = 0x1; // sign and magnitude
|
||||
const uint32_t BITS = 0x2; // number of bits in the ADC = 2
|
||||
const uint32_t DRVCFG = 0x0; // output driver configuration = CMOS Logic
|
||||
const uint32_t DIEID = 0x0; // identifies version of IC
|
||||
const uint32_t HILOADEN = 0x0; // disable output driver for high loads
|
||||
const uint32_t FHIPEN = 0x1; // enable highpass coupling between filter and PGA.
|
||||
const uint32_t PGAIEN = 0x1; // I-Channel PGA Enable
|
||||
const uint32_t PGAQEN = 0x1; // Q-Channel PGA Enable
|
||||
const uint32_t STRMEN = 0x0; // disable DSP interface for serial streaming of data
|
||||
const uint32_t STRMSTART = 0x0; // the rising edge of this bit enables data streaming to the output, clock, data, sync and frame sync outputs.
|
||||
const uint32_t STRMSTOP = 0x0; // the rising edge of this bit disables data streaming to the output, clock, data sync and frame sync outputs.
|
||||
const uint32_t STRMBITS = 0x1; // number of bits to be streamed: I MSB, I LSB
|
||||
const uint32_t STAMPEN = 0x1; // enable frame number insertion
|
||||
const uint32_t TIMESYNCEN = 0x1; // enable the output of the time sync pulses at all times when streaming is enabled.
|
||||
const uint32_t DATASYNCEN = 0x0; // disable the sync pulses at the DATASYNC output
|
||||
const uint32_t STRMRST = 0x0; // counter reset not active
|
||||
const uint32_t LOBAND = 0x0; // L1 band
|
||||
const uint32_t REFOUTEN = 0x1; // Output clock buffer enable
|
||||
const uint32_t IXTAL = 0x1; // XTAL osscillator/buffer set to normal current
|
||||
const uint32_t ICP = 0x0; // charge pump current selection set to 0.5 mA
|
||||
const uint32_t INT_PLL = 0x1; // PLL mode set to integer-N PLL
|
||||
const uint32_t PWRSAV = 0x0; // PLL power save mode disabled
|
||||
const uint32_t RDIV = 0x10; // Set the PLL reference division ratio such that the L1 band is tuned to 1575.42 Mhz
|
||||
const uint32_t FDIV = 0x80000; // PLL fractional division ratio not used. Set to default value
|
||||
const uint32_t EXTADCCLK = 0x0; // use internally generated clock
|
||||
const uint32_t REFCLK_L_CNT = 0x100; // set the L counter of the reference clock configuration to its default value
|
||||
const uint32_t REFCLK_M_CNT = 0x61B; // set the M counter of the reference clock configuration to its default value
|
||||
const uint32_t FCLKIN = 0x0; // fractional clock divider set to default value
|
||||
const uint32_t ADCCLK = 0x0; // ADC clock selection set to reference clock divider/multiplier
|
||||
const uint32_t MODE = 0x0; // DSP interface mode selection
|
||||
const uint32_t ADCCLK_L_CNT = 0x100; // set the L counter of the ADC clock configuration to its default value
|
||||
const uint32_t ADCCLK_M_CNT = 0x61B; // set the M counter of the ADC clock configuration to its default value
|
||||
const uint32_t PRE_FRACDIV_SEL = 0x0; // bypass fractional clock divider
|
||||
const uint32_t CLKOUT_SEL = 0x1; // CLKOUT selection set to ADC clock
|
||||
// MAX2771 configuration register registers
|
||||
const uint32_t TEST_MODE_1_REG_VAL = 0x01E0F401; // reserved
|
||||
const uint32_t TEST_MODE_2_REG_VAL = 0x00000002;
|
||||
|
||||
bool configure(std::vector<uint32_t> register_values);
|
||||
void run_buffer_monitor_process();
|
||||
|
||||
|
||||
std::thread thread_buffer_monitor;
|
||||
|
||||
std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga;
|
||||
std::shared_ptr<Fpga_spidev> spidev_fpga;
|
||||
|
||||
std::mutex buffer_monitor_mutex;
|
||||
|
||||
uint64_t freq_; // frequency of local oscillator
|
||||
uint64_t sample_rate_;
|
||||
|
||||
uint32_t in_stream_;
|
||||
uint32_t out_stream_;
|
||||
uint32_t bandwidth_; // 2500000, 4200000, 8700000, 16400000, 23400000, 36000000
|
||||
uint32_t filter_order_; //3, 5
|
||||
uint32_t gain_in_; // 0 to 0x3F
|
||||
|
||||
size_t item_size_; // 1
|
||||
|
||||
bool chipen_; // chip enable
|
||||
bool if_filter_gain_; // true, false
|
||||
bool LNA_active_; // true, false
|
||||
bool enable_agc_; // true, false
|
||||
bool enable_ovf_check_buffer_monitor_active_;
|
||||
bool dump_;
|
||||
bool rf_shutdown_;
|
||||
};
|
||||
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_MAX2771_EVKIT_FPGA_SIGNAL_SOURCE_H
|
@ -12,17 +12,24 @@ if(ENABLE_FMCOMMS2 OR ENABLE_AD9361)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad9361_manager.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FPGA OR ENABLE_AD9361)
|
||||
if(ENABLE_FPGA_MAX2771_EVKIT)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_spidev.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_spidev.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FPGA)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_switch.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_switch.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dynamic_bit_selection.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dynamic_bit_selection.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dma-proxy.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dma-proxy.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_AD9361 OR ENABLE_FPGA_MAX2771_EVKIT)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h)
|
||||
endif()
|
||||
|
||||
if(ENABLE_PLUTOSDR)
|
||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_samples.cc)
|
||||
|
131
src/algorithms/signal_source/libs/fpga_spidev.cc
Normal file
131
src/algorithms/signal_source/libs/fpga_spidev.cc
Normal file
@ -0,0 +1,131 @@
|
||||
/*!
|
||||
* \file fpga_spidev.cc
|
||||
* \brief FPGA SPI control.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* 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 "fpga_spidev.h"
|
||||
#include <cstring> // for memset()
|
||||
#include <fcntl.h> // for open(), O_RDWR
|
||||
#include <iostream> // for std::cerr
|
||||
#include <linux/spi/spidev.h> // spidev driver
|
||||
#include <sys/ioctl.h> // for ioctl()
|
||||
#include <unistd.h> // for close()
|
||||
|
||||
|
||||
int Fpga_spidev::SPI_open()
|
||||
{
|
||||
if ((d_fd = open(SPI_DEVICE_NAME.c_str(), O_RDWR)) < 0)
|
||||
{
|
||||
std::cerr << "Failed to open the " << SPI_DEVICE_NAME << " device file \n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret;
|
||||
int32_t mode = 0;
|
||||
|
||||
ret = ioctl(d_fd, SPI_IOC_WR_MODE32, &mode);
|
||||
if (ret == -1)
|
||||
{
|
||||
std::cerr << "can't set spi mode\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ioctl(d_fd, SPI_IOC_RD_MODE32, &mode); // le digo al spi "algo"
|
||||
if (ret == -1)
|
||||
{
|
||||
std::cerr << "can't set spi mode\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Fpga_spidev::write_reg32(char addr, uint32_t data)
|
||||
{
|
||||
uint8_t data_buffer[2];
|
||||
uint8_t recv_buffer[4];
|
||||
int res = 0;
|
||||
struct spi_ioc_transfer xfer[2];
|
||||
memset(xfer, 0, sizeof(xfer));
|
||||
xfer[0].bits_per_word = 8;
|
||||
xfer[0].speed_hz = SPI_SPEED;
|
||||
xfer[1].bits_per_word = 8;
|
||||
xfer[1].speed_hz = SPI_SPEED;
|
||||
|
||||
memset(&recv_buffer, 0, sizeof(recv_buffer));
|
||||
memset(&data_buffer, 0, sizeof(data_buffer));
|
||||
|
||||
data_buffer[1] = addr << 4 | 0 << 3;
|
||||
xfer[0].tx_buf = (unsigned long)data_buffer;
|
||||
xfer[0].len = 2;
|
||||
|
||||
// Would use memcpy but 'data' is in little endian
|
||||
((char*)recv_buffer)[0] = ((char*)&data)[3];
|
||||
((char*)recv_buffer)[1] = ((char*)&data)[2];
|
||||
((char*)recv_buffer)[2] = ((char*)&data)[1];
|
||||
((char*)recv_buffer)[3] = ((char*)&data)[0];
|
||||
|
||||
xfer[1].tx_buf = (unsigned long)recv_buffer;
|
||||
xfer[1].len = 4;
|
||||
res = ioctl(d_fd, SPI_IOC_MESSAGE(2), xfer);
|
||||
if (res < 0)
|
||||
{
|
||||
std::cout << "Error sending SPI message\n";
|
||||
return res;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Fpga_spidev::read_reg32(uint8_t addr, uint32_t* copy_to)
|
||||
{
|
||||
uint8_t data_buffer[2];
|
||||
uint8_t recv_buffer[4];
|
||||
int res;
|
||||
struct spi_ioc_transfer xfer[2];
|
||||
memset(xfer, 0, sizeof(xfer));
|
||||
xfer[0].bits_per_word = 8;
|
||||
xfer[0].speed_hz = SPI_SPEED;
|
||||
xfer[1].bits_per_word = 8;
|
||||
xfer[1].speed_hz = SPI_SPEED;
|
||||
|
||||
memset(&recv_buffer, 0, sizeof(recv_buffer));
|
||||
memset(&data_buffer, 0, sizeof(data_buffer));
|
||||
|
||||
data_buffer[1] = addr << 4 | 1 << 3;
|
||||
xfer[0].tx_buf = (unsigned long)data_buffer;
|
||||
xfer[0].len = 2;
|
||||
|
||||
xfer[1].rx_buf = (unsigned long)recv_buffer;
|
||||
xfer[1].len = 4;
|
||||
res = ioctl(d_fd, SPI_IOC_MESSAGE(2), xfer);
|
||||
if (res < 0)
|
||||
{
|
||||
std::cout << "Error sending SPI message\n";
|
||||
return res;
|
||||
}
|
||||
|
||||
// the register data is received in the reverse order
|
||||
uint32_t tmp_result = 0;
|
||||
for (uint32_t k = 0; k < 4; ++k)
|
||||
{
|
||||
tmp_result = tmp_result + ((recv_buffer[3 - k]) << 8 * k);
|
||||
}
|
||||
*copy_to = tmp_result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Fpga_spidev::SPI_close() const
|
||||
{
|
||||
return close(d_fd);
|
||||
}
|
61
src/algorithms/signal_source/libs/fpga_spidev.h
Normal file
61
src/algorithms/signal_source/libs/fpga_spidev.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*!
|
||||
* \file fpga_spidev.h
|
||||
* \brief FPGA SPI control.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* 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_FPGA_SPIDEV_H
|
||||
#define GNSS_SDR_FPGA_SPIDEV_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class Fpga_spidev
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* \brief Default constructor.
|
||||
*/
|
||||
Fpga_spidev() = default;
|
||||
|
||||
/*!
|
||||
* \brief Default destructor.
|
||||
*/
|
||||
~Fpga_spidev() = default;
|
||||
|
||||
/*!
|
||||
* \brief write a register through the SPI.
|
||||
*/
|
||||
int write_reg32(char addr, uint32_t data);
|
||||
|
||||
/*!
|
||||
* \brief read a register through the SPI.
|
||||
*/
|
||||
int read_reg32(uint8_t addr, uint32_t* copy_to);
|
||||
/*!
|
||||
* \brief Open the SPI device driver.
|
||||
*/
|
||||
int SPI_open(void);
|
||||
|
||||
/*!
|
||||
* \brief Close the SPI device driver
|
||||
*/
|
||||
int SPI_close(void) const;
|
||||
|
||||
private:
|
||||
static const uint32_t SPI_SPEED = 250000;
|
||||
const std::string SPI_DEVICE_NAME = std::string("/dev/spidev2.0"); // Switch UIO device name
|
||||
|
||||
int d_fd;
|
||||
};
|
||||
|
||||
|
||||
#endif // GNSS_SDR_FPGA_SPIDEV_H
|
@ -98,6 +98,10 @@ if(ENABLE_AD9361)
|
||||
target_compile_definitions(core_receiver PRIVATE -DAD9361_DRIVER=1)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FPGA_MAX2771_EVKIT)
|
||||
target_compile_definitions(core_receiver PRIVATE -DFPGA_MAX2771_EVKIT_DRIVER=1)
|
||||
endif()
|
||||
|
||||
if(ENABLE_OSMOSDR)
|
||||
if(GROSMOSDR_FOUND)
|
||||
target_compile_definitions(core_receiver PRIVATE -DOSMOSDR_DRIVER=1)
|
||||
|
@ -171,6 +171,10 @@
|
||||
#include "ad9361_fpga_signal_source.h"
|
||||
#endif
|
||||
|
||||
#if FPGA_MAX2771_EVKIT_DRIVER
|
||||
#include "max2771_evkit_fpga_signal_source.h"
|
||||
#endif
|
||||
|
||||
#if LIMESDR_DRIVER
|
||||
#include "limesdr_signal_source.h"
|
||||
#endif
|
||||
@ -813,8 +817,6 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
#endif
|
||||
|
||||
#if ENABLE_FPGA and AD9361_DRIVER
|
||||
// The AD9361_DRIVER Driver must be instantiated last. In this way, when using the FPGA, and when using the GNSS receiver
|
||||
// in post-processing mode, the receiver is configured and ready when the DMA starts sending samples to the receiver.
|
||||
else if (implementation == "Ad9361_Fpga_Signal_Source")
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<Ad9361FpgaSignalSource>(configuration, role, in_streams,
|
||||
@ -823,6 +825,15 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_FPGA and FPGA_MAX2771_EVKIT_DRIVER
|
||||
else if (implementation == "MAX2771_evkit_Fpga_Signal_Source")
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<MAX2771EVKITFpgaSignalSource>(configuration, role, in_streams,
|
||||
out_streams, queue);
|
||||
block = std::move(block_);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_FPGA
|
||||
else if (implementation == "DMA_Fpga_Signal_Source")
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user