diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc
index 0c41eb84c..2463efd9e 100644
--- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc
+++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc
@@ -3,7 +3,10 @@
* \brief signal source for Analog Devices front-end AD9361 connected directly to 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.
- * \author Javier Arribas, jarribas(at)cttc.es
+ * \authors
+ * - Javier Arribas, jarribas(at)cttc.es
+ *
- Marc Majoral, mmajoral(at)cttc.es
+ *
*
* -------------------------------------------------------------------------
*
@@ -288,6 +291,18 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
}
}
+ // dynamic bits selection
+ enable_dynamic_bit_selection_ = configuration->property(role + ".enable_dynamic_bit_selection", true);
+ if (enable_dynamic_bit_selection_)
+ {
+ std::string dynamic_bit_selection_default_device_name1 = "/dev/uio48";
+ std::string device_name1 = configuration->property(role + ".dyn_bits_sel_devicename", dynamic_bit_selection_default_device_name1);
+ std::string dynamic_bit_selection_default_device_name2 = "/dev/uio49";
+ std::string device_name2 = configuration->property(role + ".dyn_bits_sel_devicename", dynamic_bit_selection_default_device_name2);
+ dynamic_bit_selection_fpga = std::make_shared(device_name1, device_name2);
+ 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";
@@ -335,6 +350,22 @@ Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource()
}
}
}
+
+ std::unique_lock lock(dynamic_bit_selection_mutex);
+ bool bit_selection_enabled = enable_dynamic_bit_selection_;
+ lock.unlock();
+
+ if (bit_selection_enabled == true)
+ {
+ std::unique_lock lock(dynamic_bit_selection_mutex);
+ enable_dynamic_bit_selection_ = false;
+ lock.unlock();
+
+ if (thread_dynamic_bit_selection.joinable())
+ {
+ thread_dynamic_bit_selection.join();
+ }
+ }
}
@@ -576,6 +607,23 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &FreqBand, const
}
}
+void Ad9361FpgaSignalSource::run_dynamic_bit_selection_process(void)
+{
+ 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 lock(dynamic_bit_selection_mutex);
+ if (enable_dynamic_bit_selection_ == false)
+ {
+ dynamic_bit_selection_active = false;
+ }
+ lock.unlock();
+ }
+}
void Ad9361FpgaSignalSource::connect(gr::top_block_sptr top_block)
{
diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h
index 9b9095f4f..b98960c63 100644
--- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h
+++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h
@@ -22,6 +22,7 @@
#define GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H
#include "concurrent_queue.h"
+#include "fpga_dynamic_bit_selection.h"
#include "fpga_switch.h"
#include "gnss_block_interface.h"
#include
@@ -66,13 +67,20 @@ public:
gr::basic_block_sptr get_right_block() override;
private:
+ // perform dynamic bit selection every 500 ms by default
+ static const uint32_t Gain_control_period_ms = 500;
+
void run_DMA_process(const std::string &FreqBand,
const std::string &Filename1,
const std::string &Filename2);
+ void run_dynamic_bit_selection_process(void);
+
std::thread thread_file_to_dma;
+ std::thread thread_dynamic_bit_selection;
std::shared_ptr switch_fpga;
+ std::shared_ptr dynamic_bit_selection_fpga;
std::string role_;
@@ -115,9 +123,11 @@ private:
bool rx1_enable_;
bool rx2_enable_;
bool enable_DMA_;
+ bool enable_dynamic_bit_selection_;
bool rf_shutdown_;
std::mutex dma_mutex;
+ std::mutex dynamic_bit_selection_mutex;
};
#endif // GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H
diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt
index 4678b83d8..2794a2f03 100644
--- a/src/algorithms/signal_source/libs/CMakeLists.txt
+++ b/src/algorithms/signal_source/libs/CMakeLists.txt
@@ -17,6 +17,8 @@ endif()
if(ENABLE_FPGA OR ENABLE_AD9361)
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)
endif()
set(SIGNAL_SOURCE_LIB_SOURCES
diff --git a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc
new file mode 100644
index 000000000..d9b8bb6ab
--- /dev/null
+++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc
@@ -0,0 +1,138 @@
+/*!
+ * \file fpga_dynamic_bit_selection.cc
+ * \brief Dynamic Bit Selection in the received signal.
+ * \authors
+ * - Marc Majoral, 2020. mmajoral(at)cttc.es
+ *
+ *
+ * Class that controls the Dynamic Bit Selection in the FPGA.
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "fpga_dynamic_bit_selection.h"
+#include
+#include // for open, O_RDWR, O_SYNC
+#include // for cout
+#include // for mmap
+
+Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(const std::string &device_name1, const std::string &device_name2)
+{
+ // dynamic bits selection corresponding to frequency band 1
+ if ((d_device_descriptor1 = open(device_name1.c_str(), O_RDWR | O_SYNC)) == -1)
+ {
+ LOG(WARNING) << "Cannot open deviceio" << device_name1;
+ }
+ d_map_base1 = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE,
+ PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor1, 0));
+
+ if (d_map_base1 == reinterpret_cast(-1))
+ {
+ LOG(WARNING) << "Cannot map the FPGA dynamic bit selection module in frequency band 1 into tracking memory";
+ std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 1.\n";
+ }
+
+ // dynamic bits selection corresponding to frequency band 2
+ if ((d_device_descriptor2 = open(device_name2.c_str(), O_RDWR | O_SYNC)) == -1)
+ {
+ LOG(WARNING) << "Cannot open deviceio" << device_name2;
+ }
+ d_map_base2 = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE,
+ PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor2, 0));
+
+ if (d_map_base2 == reinterpret_cast(-1))
+ {
+ LOG(WARNING) << "Cannot map the FPGA dynamic bit selection module in frequency band 2 into tracking memory";
+ std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 2.\n";
+ }
+
+ // initialize default bit selection
+ shift_out_bits_band1 = shift_out_bits_default;
+ shift_out_bits_band2 = shift_out_bits_default;
+
+ DLOG(INFO) << "Dynamic bit selection FPGA class created";
+}
+
+
+Fpga_dynamic_bit_selection::~Fpga_dynamic_bit_selection()
+{
+ close_devices();
+}
+
+
+void Fpga_dynamic_bit_selection::bit_selection(void)
+{
+ // estimated signal power corresponding to frequency band 1
+ uint32_t rx_signal_power1 = d_map_base1[1];
+ // estimated signal power corresponding to frequency band 2
+ uint32_t rx_signal_power2 = d_map_base2[1];
+
+ // dynamic bit selection corresponding to frequency band 1
+ if (rx_signal_power1 > Power_Threshold_High)
+ {
+ if (shift_out_bits_band1 < shift_out_bit_max)
+ {
+ shift_out_bits_band1 = shift_out_bits_band1 + 1;
+ }
+ }
+ else if (rx_signal_power1 < Power_Threshold_Low)
+ {
+ if (shift_out_bits_band1 > shift_out_bits_min)
+ {
+ shift_out_bits_band1 = shift_out_bits_band1 - 1;
+ }
+ }
+
+ // dynamic bit selection corresponding to frequency band 2
+ if (rx_signal_power2 > Power_Threshold_High)
+ {
+ if (shift_out_bits_band2 < shift_out_bit_max)
+ {
+ shift_out_bits_band2 = shift_out_bits_band2 + 1;
+ }
+ }
+ else if (rx_signal_power2 < Power_Threshold_Low)
+ {
+ if (shift_out_bits_band2 > shift_out_bits_min)
+ {
+ shift_out_bits_band2 = shift_out_bits_band2 - 1;
+ }
+ }
+
+ // update bit selection corresopnding to frequency band 1
+ d_map_base1[0] = shift_out_bits_band1;
+
+ // udpate bit selection corresponding to frequency band 2
+ d_map_base2[0] = shift_out_bits_band2;
+}
+
+
+void Fpga_dynamic_bit_selection::close_devices()
+{
+ auto *aux = const_cast(d_map_base1);
+ if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1)
+ {
+ std::cout << "Failed to unmap memory uio\n";
+ }
+
+ aux = const_cast(d_map_base2);
+ if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1)
+ {
+ std::cout << "Failed to unmap memory uio\n";
+ }
+
+ close(d_device_descriptor1);
+ close(d_device_descriptor2);
+}
diff --git a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h
new file mode 100644
index 000000000..b2e8073d2
--- /dev/null
+++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h
@@ -0,0 +1,80 @@
+/*!
+ * \file fpga_dynamic_bit_selection.h
+ * \brief Dynamic bit selection in the received signal.
+ * \authors
+ * - Marc Majoral, 2020. mmajoral(at)cttc.es
+ *
+ *
+ * Class that controls the Dynamic Bit Selection in the FPGA.
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef GNSS_SDR_FPGA_DYNAMIC_BIT_SELECTION_H
+#define GNSS_SDR_FPGA_DYNAMIC_BIT_SELECTION_H
+
+#include
+#include
+#include
+
+/*!
+ * \brief Class that controls the switch in the FPGA, which connects the FPGA acquisition and multicorrelator modules to
+ * either the DMA or the Analog Front-End.
+ */
+class Fpga_dynamic_bit_selection
+{
+public:
+ /*!
+ * \brief Constructor
+ */
+ explicit Fpga_dynamic_bit_selection(const std::string& device_name1, const std::string& device_name2);
+
+ /*!
+ * \brief Destructor
+ */
+ ~Fpga_dynamic_bit_selection();
+
+ /*!
+ * \brief This function configures the switch in th eFPGA
+ */
+ // void set_switch_position(int32_t switch_position);
+ void bit_selection(void);
+
+private:
+ static const size_t FPGA_PAGE_SIZE = 0x10000;
+
+ static const uint32_t Num_bits_ADC = 12; // Number of bits in the ADC
+ static const uint32_t Num_bits_FPGA = 4; // Number of bits after the bit selection
+ static const uint32_t shift_out_bits_default = Num_bits_ADC - Num_bits_FPGA; // take the most significant bits by default
+ static const uint32_t shift_out_bits_min = 0; // minimum possible value for the bit selection
+ static const uint32_t shift_out_bit_max = Num_bits_ADC - Num_bits_FPGA; // maximum possible value for the bit selection
+ // received signal power thresholds for the bit selection
+ // the received signal power is estimated as the averaged squared absolute value of the received signal samples
+ static const uint32_t Power_Threshold_High = 15000;
+ static const uint32_t Power_Threshold_Low = 6000;
+
+ void close_devices(void);
+
+ uint32_t shift_out_bits_band1; // number of bits to shift for frequency band 1
+ uint32_t shift_out_bits_band2; // number of bits to shift for frequency band 2
+
+ volatile unsigned* d_map_base1; // driver memory map corresponding to frequency band 1
+ int d_device_descriptor1; // driver descriptor corresponding to frequency band 1
+
+ volatile unsigned* d_map_base2; // driver memory map corresponding to frequency band 2
+ int d_device_descriptor2; // driver descriptor corresponding to frequency band 2
+};
+
+#endif // GNSS_SDR_FPGA_DYNAMIC_BIT_SELECTION_H