1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-06-18 11:09:56 +00:00

Added Galileo E1 acquisition + tracking classes that use the generic acquisition and tracking classes for the FPGA HW accelerators (still to be tested). Did some minor code cleaning to the GPS files that use the FPGA HW accelerator.

This commit is contained in:
mmajoral 2018-05-22 12:25:14 +02:00
parent 0b9b9f4c39
commit 75cbc3fcdd
15 changed files with 1010 additions and 125 deletions

View File

@ -37,7 +37,7 @@ set(ACQ_ADAPTER_SOURCES
)
if(ENABLE_FPGA)
set(ACQ_ADAPTER_SOURCES ${ACQ_ADAPTER_SOURCES} gps_l1_ca_pcps_acquisition_fpga.cc)
set(ACQ_ADAPTER_SOURCES ${ACQ_ADAPTER_SOURCES} gps_l1_ca_pcps_acquisition_fpga.cc galileo_e1_pcps_ambiguous_acquisition_fpga.cc)
endif(ENABLE_FPGA)
if(OPENCL_FOUND)

View File

@ -0,0 +1,428 @@
/*!
* \file galileo_e1_pcps_ambiguous_acquisition.cc
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Galileo E1 Signals
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "galileo_e1_pcps_ambiguous_acquisition_fpga.h"
#include "configuration_interface.h"
#include "galileo_e1_signal_processing.h"
#include "Galileo_E1.h"
#include "gnss_sdr_flags.h"
#include <boost/lexical_cast.hpp>
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h>
#define NUM_PRNs_GALILEO_E1 50
using google::LogMessage;
GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{
printf("galileo e1 fpga constructor called\n");
pcpsconf_fpga_t acq_parameters;
configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./data/acquisition.dat";
DLOG(INFO) << "role " << role;
// item_type_ = configuration_->property(role + ".item_type", default_item_type);
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000);
long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in;
if_ = configuration_->property(role + ".if", 0);
acq_parameters.freq = if_;
dump_ = configuration_->property(role + ".dump", false);
// acq_parameters.dump = dump_;
blocking_ = configuration_->property(role + ".blocking", true);
// acq_parameters.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_;
unsigned int sampled_ms = 4;
acq_parameters.sampled_ms = sampled_ms;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
// acq_parameters.bit_transition_flag = bit_transition_flag_;
// use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
// acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions
// max_dwells_ = configuration_->property(role + ".max_dwells", 1);
// acq_parameters.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
// acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code (4 ms) -----------------
unsigned int code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)));
//acq_parameters.samples_per_code = code_length_;
//int samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001));
//acq_parameters.samples_per_ms = samples_per_ms;
//unsigned int vector_length = sampled_ms * samples_per_ms;
// if (bit_transition_flag_)
// {
// vector_length_ *= 2;
// }
// The FPGA can only use FFT lengths that are a power of two.
float nbits = ceilf(log2f((float)code_length));
unsigned int nsamples_total = pow(2, nbits);
unsigned int vector_length = nsamples_total;
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
acq_parameters.select_queue_Fpga = select_queue_Fpga;
std::string default_device_name = "/dev/uio0";
std::string device_name = configuration_->property(role + ".devicename", default_device_name);
acq_parameters.device_name = device_name;
acq_parameters.samples_per_ms = nsamples_total/sampled_ms;
acq_parameters.samples_per_code = nsamples_total;
// compute all the GALILEO E1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
// a channel is assigned)
gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT
std::complex<float>* code = new std::complex<float>[nsamples_total]; // buffer for the local code
gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs_GALILEO_E1]; // memory containing all the possible fft codes for PRN 0 to 32
float max; // temporary maxima search
for (unsigned int PRN = 1; PRN <= NUM_PRNs_GALILEO_E1; PRN++)
{
//code_ = new gr_complex[vector_length_];
bool cboc = false; // cboc is set to 0 when using the FPGA
//std::complex<float>* code = new std::complex<float>[code_length_];
if (acquire_pilot_ == true)
{
//set local signal generator to Galileo E1 pilot component (1C)
char pilot_signal[3] = "1C";
galileo_e1_code_gen_complex_sampled(code, pilot_signal,
cboc, gnss_synchro_->PRN, fs_in, 0, false);
}
else
{
galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal,
cboc, gnss_synchro_->PRN, fs_in, 0, false);
}
// for (unsigned int i = 0; i < sampled_ms / 4; i++)
// {
// //memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_);
// memcpy(&(d_all_fft_codes_[i * code_length_]), code, sizeof(gr_complex) * code_length_);
// }
// // fill in zero padding
for (int s = code_length; s < nsamples_total; s++)
{
code[s] = 0;
}
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
fft_if->execute(); // Run the FFT of local code
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
// normalize the code
max = 0; // initialize maximum value
for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima
{
if (std::abs(fft_codes_padded[i].real()) > max)
{
max = std::abs(fft_codes_padded[i].real());
}
if (std::abs(fft_codes_padded[i].imag()) > max)
{
max = std::abs(fft_codes_padded[i].imag());
}
}
for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs
{
d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)),
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max)));
}
}
//acq_parameters
acq_parameters.all_fft_codes = d_all_fft_codes_;
// temporary buffers that we can delete
delete[] code;
delete fft_if;
delete[] fft_codes_padded;
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
// stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_);
// DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
// if (item_type_.compare("cbyte") == 0)
// {
// cbyte_to_float_x2_ = make_complex_byte_to_float_x2();
// float_to_complex_ = gr::blocks::float_to_complex::make();
// }
channel_ = 0;
//threshold_ = 0.0;
doppler_step_ = 0;
gnss_synchro_ = 0;
}
GalileoE1PcpsAmbiguousAcquisitionFpga::~GalileoE1PcpsAmbiguousAcquisitionFpga()
{
//delete[] code_;
delete[] d_all_fft_codes_;
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_channel(unsigned int channel)
{
channel_ = channel;
acquisition_fpga_->set_channel(channel_);
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_threshold(float threshold)
{
// the .pfa parameter and the threshold calculation is only used for the CFAR algorithm.
// We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such.
// float pfa = configuration_->property(role_ + boost::lexical_cast<std::string>(channel_) + ".pfa", 0.0);
//
// if (pfa == 0.0) pfa = configuration_->property(role_ + ".pfa", 0.0);
//
// if (pfa == 0.0)
// {
// threshold_ = threshold;
// }
// else
// {
// threshold_ = calculate_threshold(pfa);
// }
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold;
acquisition_fpga_->set_threshold(threshold);
// acquisition_fpga_->set_threshold(threshold_);
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_max(unsigned int doppler_max)
{
doppler_max_ = doppler_max;
acquisition_fpga_->set_doppler_max(doppler_max_);
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
{
doppler_step_ = doppler_step;
acquisition_fpga_->set_doppler_step(doppler_step_);
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
{
gnss_synchro_ = gnss_synchro;
acquisition_fpga_->set_gnss_synchro(gnss_synchro_);
}
signed int GalileoE1PcpsAmbiguousAcquisitionFpga::mag()
{
return acquisition_fpga_->mag();
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::init()
{
acquisition_fpga_->init();
//set_local_code();
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_local_code()
{
// bool cboc = configuration_->property(
// "Acquisition" + boost::lexical_cast<std::string>(channel_) + ".cboc", false);
//
// std::complex<float>* code = new std::complex<float>[code_length_];
//
// if (acquire_pilot_ == true)
// {
// //set local signal generator to Galileo E1 pilot component (1C)
// char pilot_signal[3] = "1C";
// galileo_e1_code_gen_complex_sampled(code, pilot_signal,
// cboc, gnss_synchro_->PRN, fs_in_, 0, false);
// }
// else
// {
// galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal,
// cboc, gnss_synchro_->PRN, fs_in_, 0, false);
// }
//
//
// for (unsigned int i = 0; i < sampled_ms_ / 4; i++)
// {
// memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_);
// }
//acquisition_fpga_->set_local_code(code_);
acquisition_fpga_->set_local_code();
// delete[] code;
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::reset()
{
acquisition_fpga_->set_active(true);
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_state(int state)
{
acquisition_fpga_->set_state(state);
}
//float GalileoE1PcpsAmbiguousAcquisitionFpga::calculate_threshold(float pfa)
//{
// unsigned int frequency_bins = 0;
// for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_)
// {
// frequency_bins++;
// }
//
// DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
//
// unsigned int ncells = vector_length_ * frequency_bins;
// double exponent = 1 / static_cast<double>(ncells);
// double val = pow(1.0 - pfa, exponent);
// double lambda = double(vector_length_);
// boost::math::exponential_distribution<double> mydist(lambda);
// float threshold = static_cast<float>(quantile(mydist, val));
//
// return threshold;
//}
void GalileoE1PcpsAmbiguousAcquisitionFpga::connect(gr::top_block_sptr top_block)
{
// if (item_type_.compare("gr_complex") == 0)
// {
// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0);
// }
// else if (item_type_.compare("cshort") == 0)
// {
// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0);
// }
// else if (item_type_.compare("cbyte") == 0)
// {
// top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
// top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
// top_block->connect(float_to_complex_, 0, stream_to_vector_, 0);
// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0);
// }
// else
// {
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
// }
// nothing to connect
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
{
// if (item_type_.compare("gr_complex") == 0)
// {
// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0);
// }
// else if (item_type_.compare("cshort") == 0)
// {
// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0);
// }
// else if (item_type_.compare("cbyte") == 0)
// {
// // Since a byte-based acq implementation is not available,
// // we just convert cshorts to gr_complex
// top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
// top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
// top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0);
// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0);
// }
// else
// {
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
// }
// nothing to disconnect
}
gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_left_block()
{
// if (item_type_.compare("gr_complex") == 0)
// {
// return stream_to_vector_;
// }
// else if (item_type_.compare("cshort") == 0)
// {
// return stream_to_vector_;
// }
// else if (item_type_.compare("cbyte") == 0)
// {
// return cbyte_to_float_x2_;
// }
// else
// {
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
return nullptr;
// }
}
gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_right_block()
{
return acquisition_fpga_;
}

View File

@ -0,0 +1,172 @@
/*!
* \file galileo_e1_pcps_ambiguous_acquisition.h
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Galileo E1 Signals
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_
#define GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_
#include "acquisition_interface.h"
#include "gnss_synchro.h"
#include "pcps_acquisition_fpga.h"
#include "complex_byte_to_float_x2.h"
#include <gnuradio/blocks/stream_to_vector.h>
#include <gnuradio/blocks/float_to_complex.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <string>
class ConfigurationInterface;
/*!
* \brief This class adapts a PCPS acquisition block to an
* AcquisitionInterface for Galileo E1 Signals
*/
class GalileoE1PcpsAmbiguousAcquisitionFpga : public AcquisitionInterface
{
public:
GalileoE1PcpsAmbiguousAcquisitionFpga(ConfigurationInterface* configuration,
std::string role, unsigned int in_streams,
unsigned int out_streams);
virtual ~GalileoE1PcpsAmbiguousAcquisitionFpga();
inline std::string role() override
{
return role_;
}
/*!
* \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition"
*/
inline std::string implementation() override
{
return "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga";
}
size_t item_size() override
{
size_t item_size = sizeof(lv_16sc_t);
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;
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to efficiently exchange synchronization data between acquisition and
* tracking blocks
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
/*!
* \brief Set acquisition channel unique ID
*/
void set_channel(unsigned int channel) override;
/*!
* \brief Set statistics threshold of PCPS algorithm
*/
void set_threshold(float threshold) override;
/*!
* \brief Set maximum Doppler off grid search
*/
void set_doppler_max(unsigned int doppler_max) override;
/*!
* \brief Set Doppler steps for the grid search
*/
void set_doppler_step(unsigned int doppler_step) override;
/*!
* \brief Initializes acquisition algorithm.
*/
void init() override;
/*!
* \brief Sets local code for Galileo E1 PCPS acquisition algorithm.
*/
void set_local_code() override;
/*!
* \brief Returns the maximum peak of grid search
*/
signed int mag() override;
/*!
* \brief Restart acquisition algorithm
*/
void reset() override;
/*!
* \brief If state = 1, it forces the block to start acquiring from the first sample
*/
void set_state(int state);
private:
ConfigurationInterface* configuration_;
//pcps_acquisition_sptr acquisition_;
pcps_acquisition_fpga_sptr acquisition_fpga_;
gr::blocks::stream_to_vector::sptr stream_to_vector_;
gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
// size_t item_size_;
// std::string item_type_;
//unsigned int vector_length_;
//unsigned int code_length_;
bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_;
bool acquire_pilot_;
unsigned int channel_;
//float threshold_;
unsigned int doppler_max_;
unsigned int doppler_step_;
//unsigned int sampled_ms_;
unsigned int max_dwells_;
//long fs_in_;
long if_;
bool dump_;
bool blocking_;
std::string dump_filename_;
//std::complex<float>* code_;
Gnss_Synchro* gnss_synchro_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
//float calculate_threshold(float pfa);
// extra for the FPGA
lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts
};
#endif /* GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ */

View File

@ -73,25 +73,23 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
// The FPGA can only use FFT lengths that are a power of two.
float nbits = ceilf(log2f((float)code_length));
unsigned int nsamples_total = pow(2, nbits);
unsigned int vector_length = nsamples_total * sampled_ms;
unsigned int vector_length = nsamples_total;
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
acq_parameters.select_queue_Fpga = select_queue_Fpga;
std::string default_device_name = "/dev/uio0";
std::string device_name = configuration_->property(role + ".devicename", default_device_name);
acq_parameters.device_name = device_name;
acq_parameters.samples_per_ms = nsamples_total;
acq_parameters.samples_per_ms = nsamples_total/sampled_ms;
acq_parameters.samples_per_code = nsamples_total;
// compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
// a channel is assigned)
gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT
// allocate memory to compute all the PRNs and compute all the possible codes
std::complex<float>* code = new std::complex<float>[nsamples_total]; // buffer for the local code
gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32
float max; // temporary maxima search
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
{
gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code
@ -124,7 +122,6 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
}
//acq_parameters
acq_parameters.all_fft_codes = d_all_fft_codes_;
// temporary buffers that we can delete
@ -157,6 +154,8 @@ void GpsL1CaPcpsAcquisitionFpga::set_channel(unsigned int channel)
void GpsL1CaPcpsAcquisitionFpga::set_threshold(float threshold)
{
// the .pfa parameter and the threshold calculation is only used for the CFAR algorithm.
// We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such.
DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold;
acquisition_fpga_->set_threshold(threshold);
}
@ -226,7 +225,7 @@ void GpsL1CaPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
gr::basic_block_sptr GpsL1CaPcpsAcquisitionFpga::get_left_block()
{
return acquisition_fpga_;
return nullptr;
}

View File

@ -68,7 +68,7 @@ public:
*/
inline std::string implementation() override
{
return "GPS_L1_CA_PCPS_Acquisition";
return "GPS_L1_CA_PCPS_Acquisition_Fpga";
}
inline size_t item_size() override

View File

@ -22,7 +22,7 @@ if(ENABLE_CUDA)
endif(ENABLE_CUDA)
if(ENABLE_FPGA)
SET(OPT_TRACKING_ADAPTERS ${OPT_TRACKING_ADAPTERS} gps_l1_ca_dll_pll_tracking_fpga.cc)
SET(OPT_TRACKING_ADAPTERS ${OPT_TRACKING_ADAPTERS} gps_l1_ca_dll_pll_tracking_fpga.cc galileo_e1_dll_pll_veml_tracking_fpga.cc)
endif(ENABLE_FPGA)
set(TRACKING_ADAPTER_SOURCES

View File

@ -0,0 +1,239 @@
/*!
* \file galileo_e1_dll_pll_veml_tracking.cc
* \brief Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block
* to a TrackingInterface for Galileo E1 signals
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
*
* Code DLL + carrier PLL according to the algorithms described in:
* K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency
* Approach, Birkhauser, 2007
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "galileo_e1_dll_pll_veml_tracking_fpga.h"
#include "configuration_interface.h"
#include "Galileo_E1.h"
#include "galileo_e1_signal_processing.h"
#include "gnss_sdr_flags.h"
#include "display.h"
#include <glog/logging.h>
#define NUM_PRNs_GALILEO_E1 50
using google::LogMessage;
GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{
printf("galileo e1 fpga constructor called\n");
//dllpllconf_t trk_param;
dllpllconf_fpga_t trk_param_fpga;
DLOG(INFO) << "role " << role;
//################# CONFIGURATION PARAMETERS ########################
std::string default_item_type = "gr_complex";
std::string item_type = configuration->property(role + ".item_type", default_item_type);
int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
trk_param_fpga.fs_in = fs_in;
bool dump = configuration->property(role + ".dump", false);
trk_param_fpga.dump = dump;
float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 5.0);
if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz);
trk_param_fpga.pll_bw_hz = pll_bw_hz;
float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 0.5);
if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz);
trk_param_fpga.dll_bw_hz = dll_bw_hz;
float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 2.0);
trk_param_fpga.pll_bw_narrow_hz = pll_bw_narrow_hz;
float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 0.25);
trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz;
int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1);
float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.15);
trk_param_fpga.early_late_space_chips = early_late_space_chips;
float very_early_late_space_chips = configuration->property(role + ".very_early_late_space_chips", 0.6);
trk_param_fpga.very_early_late_space_chips = very_early_late_space_chips;
float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15);
trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips;
float very_early_late_space_narrow_chips = configuration->property(role + ".very_early_late_space_narrow_chips", 0.6);
trk_param_fpga.very_early_late_space_narrow_chips = very_early_late_space_narrow_chips;
bool track_pilot = configuration->property(role + ".track_pilot", false);
if (extend_correlation_symbols < 1)
{
extend_correlation_symbols = 1;
std::cout << TEXT_RED << "WARNING: Galileo E1. extend_correlation_symbols must be bigger than 0. Coherent integration has been set to 1 symbol (4 ms)" << TEXT_RESET << std::endl;
}
else if (!track_pilot and extend_correlation_symbols > 1)
{
extend_correlation_symbols = 1;
std::cout << TEXT_RED << "WARNING: Galileo E1. Extended coherent integration is not allowed when tracking the data component. Coherent integration has been set to 4 ms (1 symbol)" << TEXT_RESET << std::endl;
}
if ((extend_correlation_symbols > 1) and (pll_bw_narrow_hz > pll_bw_hz or dll_bw_narrow_hz > dll_bw_hz))
{
std::cout << TEXT_RED << "WARNING: Galileo E1. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << std::endl;
}
trk_param_fpga.track_pilot = track_pilot;
trk_param_fpga.extend_correlation_symbols = extend_correlation_symbols;
std::string default_dump_filename = "./track_ch";
std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename);
trk_param_fpga.dump_filename = dump_filename;
int vector_length = std::round(fs_in / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS));
trk_param_fpga.vector_length = vector_length;
trk_param_fpga.system = 'E';
char sig_[3] = "1B";
std::memcpy(trk_param_fpga.signal, sig_, 3);
int cn0_samples = configuration->property(role + ".cn0_samples", 20);
if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples;
trk_param_fpga.cn0_samples = cn0_samples;
int cn0_min = configuration->property(role + ".cn0_min", 25);
if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min;
trk_param_fpga.cn0_min = cn0_min;
int max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail;
trk_param_fpga.max_lock_fail = max_lock_fail;
double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85);
if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th;
trk_param_fpga.carrier_lock_th = carrier_lock_th;
// FPGA configuration parameters
std::string default_device_name = "/dev/uio";
std::string device_name = configuration->property(role + ".devicename", default_device_name);
trk_param_fpga.device_name = device_name;
unsigned int device_base = configuration->property(role + ".device_base", 1);
trk_param_fpga.device_base = device_base;
//################# PRE-COMPUTE ALL THE CODES #################
d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * NUM_PRNs_GALILEO_E1 * sizeof(int), volk_gnsssdr_get_alignment()));
d_data_codes = static_cast<int *>(volk_gnsssdr_malloc((static_cast<unsigned int>(Galileo_E1_B_CODE_LENGTH_CHIPS)) * 2 * NUM_PRNs_GALILEO_E1 * sizeof(int), volk_gnsssdr_get_alignment()));
float* ca_codes_f = static_cast<float*>(volk_gnsssdr_malloc(static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * sizeof(float), volk_gnsssdr_get_alignment()));
float* data_codes_f = static_cast<float *>(volk_gnsssdr_malloc((static_cast<unsigned int>(Galileo_E1_B_CODE_LENGTH_CHIPS)) * 2 * sizeof(float), volk_gnsssdr_get_alignment()));
for (unsigned int PRN = 1; PRN <= NUM_PRNs_GALILEO_E1; PRN++)
{
char data_signal[3] = "1B";
if (trk_param_fpga.track_pilot)
{
char pilot_signal[3] = "1C";
galileo_e1_code_gen_sinboc11_float(ca_codes_f, pilot_signal, PRN);
galileo_e1_code_gen_sinboc11_float(data_codes_f, data_signal, PRN);
for (unsigned int s = 0; s < Galileo_E1_B_CODE_LENGTH_CHIPS; s++)
{
d_ca_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s] = static_cast<int>(ca_codes_f[s]);
d_data_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s] = static_cast<int>(d_data_codes[s]);
}
}
else
{
galileo_e1_code_gen_sinboc11_float(ca_codes_f, data_signal, PRN);
for (unsigned int s = 0; s < Galileo_E1_B_CODE_LENGTH_CHIPS; s++)
{
d_ca_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s] = static_cast<int>(ca_codes_f[s]);
}
}
}
delete[] ca_codes_f;
delete[] data_codes_f;
trk_param_fpga.ca_codes = d_ca_codes;
trk_param_fpga.data_codes = d_data_codes;
trk_param_fpga.code_length = Galileo_E1_B_CODE_LENGTH_CHIPS;
//################# MAKE TRACKING GNURadio object ###################
tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga);
channel_ = 0;
DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")";
}
GalileoE1DllPllVemlTrackingFpga::~GalileoE1DllPllVemlTrackingFpga()
{
delete[] d_ca_codes;
delete[] d_data_codes;
}
void GalileoE1DllPllVemlTrackingFpga::start_tracking()
{
//tracking_->start_tracking();
tracking_fpga_sc->start_tracking();
}
/*
* Set tracking channel unique ID
*/
void GalileoE1DllPllVemlTrackingFpga::set_channel(unsigned int channel)
{
channel_ = channel;
//tracking_->set_channel(channel);
tracking_fpga_sc->set_channel(channel);
}
void GalileoE1DllPllVemlTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
{
//tracking_->set_gnss_synchro(p_gnss_synchro);
tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro);
}
void GalileoE1DllPllVemlTrackingFpga::connect(gr::top_block_sptr top_block)
{
if (top_block)
{ /* top_block is not null */
};
//nothing to connect, now the tracking uses gr_sync_decimator
}
void GalileoE1DllPllVemlTrackingFpga::disconnect(gr::top_block_sptr top_block)
{
if (top_block)
{ /* top_block is not null */
};
//nothing to disconnect, now the tracking uses gr_sync_decimator
}
gr::basic_block_sptr GalileoE1DllPllVemlTrackingFpga::get_left_block()
{
//return tracking_;
return tracking_fpga_sc;
}
gr::basic_block_sptr GalileoE1DllPllVemlTrackingFpga::get_right_block()
{
//return tracking_;
return tracking_fpga_sc;
}

View File

@ -0,0 +1,109 @@
/*!
* \file galileo_e1_dll_pll_veml_tracking.h
* \brief Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block
* to a TrackingInterface for Galileo E1 signals
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
*
* Code DLL + carrier PLL according to the algorithms described in:
* K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency
* Approach, Birkhauser, 2007
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_FPGA_H_
#define GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_FPGA_H_
#include "tracking_interface.h"
#include "dll_pll_veml_tracking_fpga.h"
#include <string>
class ConfigurationInterface;
/*!
* \brief This class Adapts a DLL+PLL VEML (Very Early Minus Late) tracking
* loop block to a TrackingInterface for Galileo E1 signals
*/
class GalileoE1DllPllVemlTrackingFpga : public TrackingInterface
{
public:
GalileoE1DllPllVemlTrackingFpga(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams);
virtual ~GalileoE1DllPllVemlTrackingFpga();
inline std::string role() override
{
return role_;
}
//! Returns "Galileo_E1_DLL_PLL_VEML_Tracking"
inline std::string implementation() override
{
return "Galileo_E1_DLL_PLL_VEML_Tracking";
}
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;
/*!
* \brief Set tracking channel unique ID
*/
void set_channel(unsigned int channel) override;
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to efficiently exchange synchronization data between acquisition and
* tracking blocks
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
void start_tracking() override;
private:
//dll_pll_veml_tracking_sptr tracking_;
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
size_t item_size_;
unsigned int channel_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
int* d_ca_codes;
int* d_data_codes;
};
#endif // GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_FPGA_H_

View File

@ -1,5 +1,5 @@
/*!
* \file gps_l1_ca_dll_pll_tracking.cc
* \file gps_l1_ca_dll_pll_tracking_fpga.cc
* \brief Implementation of an adapter of a DLL+PLL tracking loop block
* for GPS L1 C/A to a TrackingInterface that uses the FPGA
* \author Marc Majoral, 2018, mmajoral(at)cttc.es
@ -36,10 +36,6 @@
* -------------------------------------------------------------------------
*/
//#include <volk_gnsssdr/volk_gnsssdr.h>
#include <glog/logging.h>
#include "gps_sdr_signal_processing.h"
#include "gps_l1_ca_dll_pll_tracking_fpga.h"
@ -48,7 +44,6 @@
#include "gnss_sdr_flags.h"
#include "display.h"
#define NUM_PRNs 32
using google::LogMessage;
@ -149,91 +144,6 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
channel_ = 0;
DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")";
/*
//################# CONFIGURATION PARAMETERS ########################
int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
trk_param_fpga.fs_in = fs_in;
bool dump = configuration->property(role + ".dump", false);
trk_param_fpga.dump = dump;
float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0);
if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz);
trk_param_fpga.pll_bw_hz = pll_bw_hz;
float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 20.0);
trk_param_fpga.pll_bw_narrow_hz = pll_bw_narrow_hz;
float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 2.0);
trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz;
float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0);
if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz);
trk_param_fpga.dll_bw_hz = dll_bw_hz;
float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
trk_param_fpga.early_late_space_chips = early_late_space_chips;
float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.5);
trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips;
std::string default_dump_filename = "./track_ch";
std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename);
trk_param_fpga.dump_filename = dump_filename;
int vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
trk_param_fpga.vector_length = vector_length;
int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1);
if (symbols_extended_correlator < 1)
{
symbols_extended_correlator = 1;
std::cout << TEXT_RED << "WARNING: GPS L1 C/A. extend_correlation_symbols must be bigger than 1. Coherent integration has been set to 1 symbol (1 ms)" << TEXT_RESET << std::endl;
}
else if (symbols_extended_correlator > 20)
{
symbols_extended_correlator = 20;
std::cout << TEXT_RED << "WARNING: GPS L1 C/A. extend_correlation_symbols must be lower than 21. Coherent integration has been set to 20 symbols (20 ms)" << TEXT_RESET << std::endl;
}
trk_param_fpga.extend_correlation_symbols = symbols_extended_correlator;
bool track_pilot = configuration->property(role + ".track_pilot", false);
if (track_pilot)
{
std::cout << TEXT_RED << "WARNING: GPS L1 C/A does not have pilot signal. Data tracking has been enabled" << TEXT_RESET << std::endl;
}
if ((symbols_extended_correlator > 1) and (pll_bw_narrow_hz > pll_bw_hz or dll_bw_narrow_hz > dll_bw_hz))
{
std::cout << TEXT_RED << "WARNING: GPS L1 C/A. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << std::endl;
}
trk_param_fpga.very_early_late_space_chips = 0.0;
trk_param_fpga.very_early_late_space_narrow_chips = 0.0;
trk_param_fpga.track_pilot = false;
trk_param_fpga.system = 'G';
char sig_[3] = "1C";
std::memcpy(trk_param_fpga.signal, sig_, 3);
// FPGA configuration parameters
std::string default_device_name = "/dev/uio";
std::string device_name = configuration->property(role + ".devicename", default_device_name);
trk_param_fpga.device_name = device_name;
unsigned int device_base = configuration->property(role + ".device_base", 1);
trk_param_fpga.device_base = device_base;
//################# PRE-COMPUTE ALL THE CODES #################
d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS*NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment()));
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
{
gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0);
}
trk_param_fpga.ca_codes = d_ca_codes;
trk_param_fpga.code_length = GPS_L1_CA_CODE_LENGTH_CHIPS;
//################# MAKE TRACKING GNURadio object ###################
tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga);
channel_ = 0;
DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")";
*/
}
GpsL1CaDllPllTrackingFpga::~GpsL1CaDllPllTrackingFpga()

View File

@ -1,5 +1,5 @@
/*!
* \file gps_l1_ca_dll_pll_tracking.h
* \file gps_l1_ca_dll_pll_tracking_fpga.h
* \brief Interface of an adapter of a DLL+PLL tracking loop block
* for GPS L1 C/A to a TrackingInterface that uses the FPGA
* \author Marc Majoral, 2018. mmajoral(at)cttc.es
@ -96,7 +96,6 @@ public:
//void reset(void);
private:
//gps_l1_ca_dll_pll_tracking_cc_sptr tracking_;
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
size_t item_size_;
unsigned int channel_;

View File

@ -1,5 +1,5 @@
/*!
* \file dll_pll_veml_tracking.cc
* \file dll_pll_veml_tracking_fpga.cc
* \brief Implementation of a code DLL + carrier PLL tracking block using an FPGA
* \author Marc Majoral, 2018. marc.majoral(at)cttc.es
* Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com
@ -365,9 +365,10 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_)
std::string device_name = trk_parameters.device_name;
unsigned int device_base = trk_parameters.device_base;
int* ca_codes = trk_parameters.ca_codes;
int* data_codes = trk_parameters.data_codes;
unsigned int code_length = trk_parameters.code_length;
multicorrelator_fpga = std::make_shared <fpga_multicorrelator_8sc>(d_n_correlator_taps, device_name, device_base, ca_codes, code_length);
multicorrelator_fpga->set_output_vectors(d_correlator_outs);
multicorrelator_fpga = std::make_shared <fpga_multicorrelator_8sc>(d_n_correlator_taps, device_name, device_base, ca_codes, data_codes, code_length, trk_parameters.track_pilot);
multicorrelator_fpga->set_output_vectors(d_correlator_outs, d_Prompt_Data);
d_pull_in = 0;
}
@ -438,6 +439,7 @@ void dll_pll_veml_tracking_fpga::start_tracking()
{
char pilot_signal[3] = "1C";
d_Prompt_Data[0] = gr_complex(0.0, 0.0);
// MISSING _: set_local_code_and_taps for the data correlator
}
else
{
@ -505,7 +507,7 @@ void dll_pll_veml_tracking_fpga::start_tracking()
LOG(INFO) << "PULL-IN Doppler [Hz] = " << d_carrier_doppler_hz
<< ". Code Phase correction [samples] = " << delay_correction_samples
<< ". PULL-IN Code Phase [samples] = " << d_acq_code_phase_samples;
multicorrelator_fpga->set_local_code_and_taps(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS), d_local_code_shift_chips, d_acquisition_gnss_synchro->PRN);
multicorrelator_fpga->set_local_code_and_taps(d_code_length_chips, d_local_code_shift_chips, d_acquisition_gnss_synchro->PRN);
d_pull_in = 1;
// enable tracking pull-in and d_state at the end to avoid general work from starting pull-in before the start tracking function is finished
d_state = 1;

View File

@ -76,6 +76,7 @@ typedef struct
unsigned int device_base;
unsigned int code_length;
int* ca_codes;
int* data_codes;
} dllpllconf_fpga_t;
class dll_pll_veml_tracking_fpga;

View File

@ -104,9 +104,10 @@ void fpga_multicorrelator_8sc::set_local_code_and_taps(int code_length_chips,
fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(PRN);
}
void fpga_multicorrelator_8sc::set_output_vectors(gr_complex* corr_out)
void fpga_multicorrelator_8sc::set_output_vectors(gr_complex* corr_out, gr_complex* Prompt_Data)
{
d_corr_out = corr_out;
d_Prompt_Data = Prompt_Data;
}
void fpga_multicorrelator_8sc::update_local_code(float rem_code_phase_chips)
@ -144,11 +145,12 @@ void fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler(
}
fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int n_correlators,
std::string device_name, unsigned int device_base, int *ca_codes, unsigned int code_length)
std::string device_name, unsigned int device_base, int *ca_codes, int *data_codes, unsigned int code_length, bool track_pilot)
{
d_n_correlators = n_correlators;
d_device_name = device_name;
d_device_base = device_base;
d_track_pilot = track_pilot;
d_device_descriptor = 0;
d_map_base = nullptr;
@ -158,7 +160,6 @@ fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int n_correlators,
d_initial_interp_counter = static_cast<unsigned*>(volk_gnsssdr_malloc(
n_correlators * sizeof(unsigned), volk_gnsssdr_get_alignment()));
//d_local_code_in = nullptr;
d_shifts_chips = nullptr;
d_corr_out = nullptr;
d_code_length_chips = 0;
@ -172,13 +173,6 @@ fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int n_correlators,
d_channel = 0;
d_correlator_length_samples = 0,
d_code_length = code_length;
// pre-compute all the codes
// d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS*NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment()));
// for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
// {
// gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0);
// }
d_ca_codes = ca_codes;
DLOG(INFO) << "TRACKING FPGA CLASS CREATED";
@ -429,10 +423,6 @@ void fpga_multicorrelator_8sc::close_device()
{
printf("Failed to unmap memory uio\n");
}
/* else
{
printf("memory uio unmapped\n");
} */
close(d_device_descriptor);
}

View File

@ -49,10 +49,10 @@ class fpga_multicorrelator_8sc
{
public:
fpga_multicorrelator_8sc(int n_correlators, std::string device_name,
unsigned int device_base, int *ca_codes, unsigned int code_length);
unsigned int device_base, int *ca_codes, int *data_codes, unsigned int code_length, bool track_pilot);
~fpga_multicorrelator_8sc();
//bool set_output_vectors(gr_complex* corr_out);
void set_output_vectors(gr_complex* corr_out);
void set_output_vectors(gr_complex* corr_out, gr_complex* Prompt_Data);
// bool set_local_code_and_taps(
// int code_length_chips, const int* local_code_in,
// float *shifts_chips, int PRN);
@ -78,6 +78,7 @@ public:
private:
//const int *d_local_code_in;
gr_complex * d_corr_out;
gr_complex * d_Prompt_Data;
float *d_shifts_chips;
int d_code_length_chips;
int d_n_correlators;
@ -112,6 +113,8 @@ private:
unsigned int d_code_length; // nominal number of chips
bool d_track_pilot;
// private functions
unsigned fpga_acquisition_test_register(unsigned writeval);
void fpga_configure_tracking_gps_local_code(int PRN);
@ -123,9 +126,7 @@ private:
void read_tracking_gps_results(void);
void reset_multicorrelator(void);
void close_device(void);
// debug
//unsigned int first_time = 1;
};
#endif /* GNSS_SDR_FPGA_MULTICORRELATOR_H_ */

View File

@ -4,6 +4,7 @@
* \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
* Luis Esteve, 2012. luis(at)epsilon-formacion.com
* Javier Arribas, 2011. jarribas(at)cttc.es
* Marc Majoral, 2018. mmajoral(at)cttc.es
*
* This class encapsulates the complexity behind the instantiation
* of GNSS blocks.
@ -105,7 +106,9 @@
#if ENABLE_FPGA
#include "gps_l1_ca_pcps_acquisition_fpga.h"
#include "galileo_e1_pcps_ambiguous_acquisition_fpga.h"
#include "gps_l1_ca_dll_pll_tracking_fpga.h"
#include "galileo_e1_dll_pll_veml_tracking_fpga.h"
#endif
#if OPENCL_BLOCKS
@ -1383,6 +1386,14 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
out_streams));
block = std::move(block_);
}
#if ENABLE_FPGA
else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga") == 0)
{
std::unique_ptr<GNSSBlockInterface> block_(new GalileoE1PcpsAmbiguousAcquisitionFpga(configuration.get(), role, in_streams,
out_streams));
block = std::move(block_);
}
#endif
else if (implementation.compare("Galileo_E1_PCPS_8ms_Ambiguous_Acquisition") == 0)
{
std::unique_ptr<GNSSBlockInterface> block_(new GalileoE1Pcps8msAmbiguousAcquisition(configuration.get(), role, in_streams,
@ -1484,6 +1495,14 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
out_streams));
block = std::move(block_);
}
#if ENABLE_FPGA
else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0)
{
std::unique_ptr<TrackingInterface> block_(new GalileoE1DllPllVemlTrackingFpga(configuration.get(), role, in_streams,
out_streams));
block = std::move(block_);
}
#endif
else if (implementation.compare("Galileo_E1_TCP_CONNECTOR_Tracking") == 0)
{
std::unique_ptr<GNSSBlockInterface> block_(new GalileoE1TcpConnectorTracking(configuration.get(), role, in_streams,
@ -1676,6 +1695,14 @@ std::unique_ptr<AcquisitionInterface> GNSSBlockFactory::GetAcqBlock(
out_streams));
block = std::move(block_);
}
#if ENABLE_FPGA
else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga") == 0)
{
std::unique_ptr<AcquisitionInterface> block_(new GalileoE1PcpsAmbiguousAcquisitionFpga(configuration.get(), role, in_streams,
out_streams));
block = std::move(block_);
}
#endif
else if (implementation.compare("Galileo_E1_PCPS_8ms_Ambiguous_Acquisition") == 0)
{
std::unique_ptr<AcquisitionInterface> block_(new GalileoE1Pcps8msAmbiguousAcquisition(configuration.get(), role, in_streams,
@ -1775,6 +1802,14 @@ std::unique_ptr<TrackingInterface> GNSSBlockFactory::GetTrkBlock(
out_streams));
block = std::move(block_);
}
#if ENABLE_FPGA
else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0)
{
std::unique_ptr<TrackingInterface> block_(new GalileoE1DllPllVemlTrackingFpga(configuration.get(), role, in_streams,
out_streams));
block = std::move(block_);
}
#endif
else if (implementation.compare("Galileo_E1_TCP_CONNECTOR_Tracking") == 0)
{
std::unique_ptr<TrackingInterface> block_(new GalileoE1TcpConnectorTracking(configuration.get(), role, in_streams,