From 98f1287f0ebe98c2d9ece832c68016ef0655c0ed Mon Sep 17 00:00:00 2001 From: Marc Majoral Date: Thu, 16 Jul 2020 15:42:55 +0200 Subject: [PATCH 1/2] dynamic bit selection based on the estimated power of the received signal. --- .../adapters/ad9361_fpga_signal_source.cc | 50 ++++++- .../adapters/ad9361_fpga_signal_source.h | 10 ++ .../signal_source/libs/CMakeLists.txt | 2 + .../libs/fpga_dynamic_bit_selection.cc | 136 ++++++++++++++++++ .../libs/fpga_dynamic_bit_selection.h | 80 +++++++++++ 5 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc create mode 100644 src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h 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 * * ------------------------------------------------------------------------- * @@ -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..17ade43d9 --- /dev/null +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc @@ -0,0 +1,136 @@ +/*! + * \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, endl +#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." << std::endl; + } + + // 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." << std::endl; + } + + // 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" << std::endl; + } + + aux = const_cast(d_map_base2); + if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1) + { + std::cout << "Failed to unmap memory uio" << std::endl; + } + + 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..4e6061143 --- /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 + +/*! + * \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 From 08fa55c5851d0fa6b4f9c2ecd0b7b63bbd164f6d Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 16 Jul 2020 19:07:58 +0200 Subject: [PATCH 2/2] Add missing includes, use \n instead of endl --- .../signal_source/libs/fpga_dynamic_bit_selection.cc | 12 +++++++----- .../signal_source/libs/fpga_dynamic_bit_selection.h | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc index 17ade43d9..d9b8bb6ab 100644 --- a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc @@ -25,7 +25,7 @@ #include "fpga_dynamic_bit_selection.h" #include #include // for open, O_RDWR, O_SYNC -#include // for cout, endl +#include // for cout #include // for mmap Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(const std::string &device_name1, const std::string &device_name2) @@ -41,7 +41,7 @@ Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(const std::string &device 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." << std::endl; + std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 1.\n"; } // dynamic bits selection corresponding to frequency band 2 @@ -55,7 +55,7 @@ Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(const std::string &device 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." << std::endl; + std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 2.\n"; } // initialize default bit selection @@ -71,6 +71,7 @@ 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 @@ -117,18 +118,19 @@ void Fpga_dynamic_bit_selection::bit_selection(void) 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" << std::endl; + 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" << std::endl; + std::cout << "Failed to unmap memory uio\n"; } close(d_device_descriptor1); diff --git a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h index 4e6061143..b2e8073d2 100644 --- a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h @@ -25,6 +25,8 @@ #ifndef GNSS_SDR_FPGA_DYNAMIC_BIT_SELECTION_H #define GNSS_SDR_FPGA_DYNAMIC_BIT_SELECTION_H +#include +#include #include /*! @@ -63,13 +65,11 @@ private: 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