1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-06-24 05:53:16 +00:00

dynamic bit selection based on the estimated power of the received signal.

This commit is contained in:
Marc Majoral 2020-07-16 15:42:55 +02:00
parent eb74cbc737
commit 98f1287f0e
5 changed files with 277 additions and 1 deletions

View File

@ -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 <ul>
* <li> Javier Arribas, jarribas(at)cttc.es
* <li> Marc Majoral, mmajoral(at)cttc.es
* </ul>
*
* -------------------------------------------------------------------------
*
@ -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<Fpga_dynamic_bit_selection>(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<std::mutex> lock(dynamic_bit_selection_mutex);
bool bit_selection_enabled = enable_dynamic_bit_selection_;
lock.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();
}
}
}
@ -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<std::mutex> 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)
{

View File

@ -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 <pmt/pmt.h>
@ -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<Fpga_Switch> switch_fpga;
std::shared_ptr<Fpga_dynamic_bit_selection> 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

View File

@ -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

View File

@ -0,0 +1,136 @@
/*!
* \file fpga_dynamic_bit_selection.cc
* \brief Dynamic Bit Selection in the received signal.
* \authors <ul>
* <li> Marc Majoral, 2020. mmajoral(at)cttc.es
* </ul>
*
* 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 <glog/logging.h>
#include <fcntl.h> // for open, O_RDWR, O_SYNC
#include <iostream> // for cout, endl
#include <sys/mman.h> // 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<volatile unsigned *>(mmap(nullptr, FPGA_PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor1, 0));
if (d_map_base1 == reinterpret_cast<void *>(-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<volatile unsigned *>(mmap(nullptr, FPGA_PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor2, 0));
if (d_map_base2 == reinterpret_cast<void *>(-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<unsigned *>(d_map_base1);
if (munmap(static_cast<void *>(aux), FPGA_PAGE_SIZE) == -1)
{
std::cout << "Failed to unmap memory uio" << std::endl;
}
aux = const_cast<unsigned *>(d_map_base2);
if (munmap(static_cast<void *>(aux), FPGA_PAGE_SIZE) == -1)
{
std::cout << "Failed to unmap memory uio" << std::endl;
}
close(d_device_descriptor1);
close(d_device_descriptor2);
}

View File

@ -0,0 +1,80 @@
/*!
* \file fpga_dynamic_bit_selection.h
* \brief Dynamic bit selection in the received signal.
* \authors <ul>
* <li> Marc Majoral, 2020. mmajoral(at)cttc.es
* </ul>
*
* 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 <string>
/*!
* \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