1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-15 04:30:33 +00:00

Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into next

This commit is contained in:
Carles Fernandez 2019-02-28 22:21:49 +01:00
commit 78d6967d52
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
70 changed files with 4112 additions and 2771 deletions

View File

@ -1,29 +1,52 @@
## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next) ## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next)
### Improvements in Availability
- Fixed bug that caused a random deadlock in the Observables block, preventing the computation of PVT fixes.
### Improvements in Efficiency ### Improvements in Efficiency
- Improved preamble detection implementation in the decoding of navigation messages (acceleration by x1.6 on average).
- Applied clang-tidy checks and fixes related to performance. - Applied clang-tidy checks and fixes related to performance.
### Improvements in Interoperability: ### Improvements in Interoperability:
- Added the BeiDou B1I receiver chain. - Added the BeiDou B1I receiver chain.
- Fix bug in GLONASS dual frequency receiver. - Fix bug in GLONASS dual frequency receiver.
### Improvements in Maintainability: ### Improvements in Maintainability:
- Usage of clang-tidy integrated into CMake scripts. New option -DENABLE_CLANG_TIDY=ON executes clang-tidy along with compilation. Requires clang compiler. - Usage of clang-tidy integrated into CMake scripts. New option -DENABLE_CLANG_TIDY=ON executes clang-tidy along with compilation. Requires clang compiler.
- Applied clang-tidy checks and fixes related to readability. - Applied clang-tidy checks and fixes related to readability.
### Improvements in Portability: ### Improvements in Portability:
- Added interfaces for FPGA off-loading.
- CMake scripts now follow a modern approach (targets and properties) but still work in 2.8.12 - CMake scripts now follow a modern approach (targets and properties) but still work in 2.8.12
## Improvements in Reliability ### Improvements in Reliability
- Applied clang-tidy checks and fixes related to High Integrity C++. - Applied clang-tidy checks and fixes related to High Integrity C++.
### Improvements in Usability
- The receiver now admits FPGA off-loading, allowing for real time operation at high sampling rates and higher number of signals and channels.
- Fixed program termination (avoiding hangs and segfaults in some platforms/configurations).
- Improved information provided to the user in case of failure.
See the definitions of concepts and metrics at https://gnss-sdr.org/design-forces/
## [0.0.10](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.10) ## [0.0.10](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.10)
This release has several improvements in different dimensions, addition of new features and bug fixes: This release has several improvements in different dimensions, addition of new features and bug fixes:

View File

@ -1,12 +1,12 @@
/*! /*!
* \file galileo_e1_pcps_ambiguous_acquisition.cc * \file galileo_e1_pcps_ambiguous_acquisition_fpga.cc
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Galileo E1 Signals * Galileo E1 Signals for the FPGA
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com * \author Marc Majoral, 2019. mmajoral(at)cttc.es
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -34,8 +34,6 @@
#include "configuration_interface.h" #include "configuration_interface.h"
#include "galileo_e1_signal_processing.h" #include "galileo_e1_signal_processing.h"
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include <boost/lexical_cast.hpp>
#include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
@ -50,75 +48,50 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
in_streams_(in_streams), in_streams_(in_streams),
out_streams_(out_streams) out_streams_(out_streams)
{ {
//printf("top acq constructor start\n");
pcpsconf_fpga_t acq_parameters; pcpsconf_fpga_t acq_parameters;
configuration_ = configuration; configuration_ = configuration;
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./acquisition.mat"; std::string default_item_type = "cshort";
std::string default_dump_filename = "./data/acquisition.dat";
DLOG(INFO) << "role " << role; DLOG(INFO) << "role " << role;
// item_type_ = configuration_->property(role + ".item_type", default_item_type);
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000);
int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); int64_t 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); float downsampling_factor = configuration_->property(role + ".downsampling_factor", 4.0);
// acq_parameters.dump = dump_; acq_parameters.downsampling_factor = downsampling_factor;
// blocking_ = configuration_->property(role + ".blocking", true);
// acq_parameters.blocking = blocking_; fs_in = fs_in / downsampling_factor;
acq_parameters.fs_in = fs_in;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000); doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_; acq_parameters.doppler_max = doppler_max_;
//unsigned int sampled_ms = 4; uint32_t sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 4);
//acq_parameters.sampled_ms = sampled_ms;
unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 4);
acq_parameters.sampled_ms = sampled_ms; 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 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) ----------------- //--- Find number of samples per spreading code (4 ms) -----------------
auto 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))); auto code_length = static_cast<uint32_t>(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;
// }
//printf("fs_in = %d\n", fs_in);
//printf("GALILEO_E1_B_CODE_LENGTH_CHIPS = %f\n", GALILEO_E1_B_CODE_LENGTH_CHIPS);
//printf("GALILEO_E1_CODE_CHIP_RATE_HZ = %f\n", GALILEO_E1_CODE_CHIP_RATE_HZ);
//printf("acq adapter code_length = %d\n", code_length);
acq_parameters.code_length = code_length; acq_parameters.code_length = code_length;
// The FPGA can only use FFT lengths that are a power of two. // The FPGA can only use FFT lengths that are a power of two.
float nbits = ceilf(log2f((float)code_length)); float nbits = ceilf(log2f((float)code_length * 2));
unsigned int nsamples_total = pow(2, nbits); uint32_t nsamples_total = pow(2, nbits);
unsigned int vector_length = nsamples_total; uint32_t select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
//printf("acq adapter nsamples_total (= vector_length) = %d\n", vector_length);
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
acq_parameters.select_queue_Fpga = select_queue_Fpga; acq_parameters.select_queue_Fpga = select_queue_Fpga;
std::string default_device_name = "/dev/uio0"; std::string default_device_name = "/dev/uio0";
std::string device_name = configuration_->property(role + ".devicename", default_device_name); std::string device_name = configuration_->property(role + ".devicename", default_device_name);
acq_parameters.device_name = device_name; acq_parameters.device_name = device_name;
acq_parameters.samples_per_ms = nsamples_total / sampled_ms; acq_parameters.samples_per_ms = nsamples_total / sampled_ms;
acq_parameters.samples_per_code = nsamples_total; acq_parameters.samples_per_code = nsamples_total;
acq_parameters.excludelimit = static_cast<uint32_t>(std::round(static_cast<double>(fs_in) / GALILEO_E1_CODE_CHIP_RATE_HZ));
// 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 // compute all the GALILEO E1 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time
// a channel is assigned) // a channel is assigned)
auto* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT auto* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT
auto* code = new std::complex<float>[nsamples_total]; // buffer for the local code auto* code = new std::complex<float>[nsamples_total]; // buffer for the local code
@ -126,19 +99,12 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
d_all_fft_codes_ = new lv_16sc_t[nsamples_total * GALILEO_E1_NUMBER_OF_CODES]; // memory containing all the possible fft codes for PRN 0 to 32 d_all_fft_codes_ = new lv_16sc_t[nsamples_total * GALILEO_E1_NUMBER_OF_CODES]; // memory containing all the possible fft codes for PRN 0 to 32
float max; // temporary maxima search float max; // temporary maxima search
//int tmp_re, tmp_im; for (uint32_t PRN = 1; PRN <= GALILEO_E1_NUMBER_OF_CODES; PRN++)
for (unsigned int PRN = 1; PRN <= GALILEO_E1_NUMBER_OF_CODES; PRN++)
{ {
//code_ = new gr_complex[vector_length_];
bool cboc = false; // cboc is set to 0 when using the FPGA 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) if (acquire_pilot_ == true)
{ {
//printf("yes acquiring pilot!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1\n");
//set local signal generator to Galileo E1 pilot component (1C) //set local signal generator to Galileo E1 pilot component (1C)
char pilot_signal[3] = "1C"; char pilot_signal[3] = "1C";
galileo_e1_code_gen_complex_sampled(code, pilot_signal, galileo_e1_code_gen_complex_sampled(code, pilot_signal,
@ -151,53 +117,24 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
cboc, PRN, fs_in, 0, false); cboc, PRN, fs_in, 0, false);
} }
// for (unsigned int i = 0; i < sampled_ms / 4; i++) for (uint32_t s = code_length; s < 2 * code_length; s++)
// { {
// //memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_); code[s] = code[s - code_length];
// memcpy(&(d_all_fft_codes_[i * code_length_]), code, sizeof(gr_complex) * code_length_); }
// }
// fill in zero padding
// // debug for (uint32_t s = 2 * code_length; s < nsamples_total; s++)
// char filename[25];
// FILE *fid;
// sprintf(filename,"gal_prn%d.txt", PRN);
// fid = fopen(filename, "w");
// for (unsigned int kk=0;kk< nsamples_total; kk++)
// {
// fprintf(fid, "%f\n", code[kk].real());
// fprintf(fid, "%f\n", code[kk].imag());
// }
// fclose(fid);
// // fill in zero padding
for (int s = code_length; s < nsamples_total; s++)
{ {
code[s] = std::complex<float>(0.0, 0.0); code[s] = std::complex<float>(0.0, 0.0);
//code[s] = 0;
} }
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
fft_if->execute(); // Run the FFT of local code fft_if->execute(); // Run the FFT of local code
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
// // debug
// char filename[25];
// FILE *fid;
// sprintf(filename,"fft_gal_prn%d.txt", PRN);
// fid = fopen(filename, "w");
// for (unsigned int kk=0;kk< nsamples_total; kk++)
// {
// fprintf(fid, "%f\n", fft_codes_padded[kk].real());
// fprintf(fid, "%f\n", fft_codes_padded[kk].imag());
// }
// fclose(fid);
// normalize the code // normalize the code
max = 0; // initialize maximum value max = 0; // initialize maximum value
for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima
{ {
if (std::abs(fft_codes_padded[i].real()) > max) if (std::abs(fft_codes_padded[i].real()) > max)
{ {
@ -208,350 +145,135 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
max = std::abs(fft_codes_padded[i].imag()); 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 for (uint32_t 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(4096*fft_codes_padded[i].real() * (pow(2, 3) - 1) / max)), d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, 9) - 1) / max)),
// static_cast<int>(floor(4096*fft_codes_padded[i].imag() * (pow(2, 3) - 1) / max))); static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max)));
// d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(1024*fft_codes_padded[i].real() * (pow(2, 5) - 1) / max)),
// static_cast<int>(floor(1024*fft_codes_padded[i].imag() * (pow(2, 5) - 1) / max)));
// d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)),
// static_cast<int>(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max)));
// d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(16*fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)),
// static_cast<int>(floor(16*fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max)));
d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)),
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max)));
// tmp_re = static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max));
// tmp_im = static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max));
// if (tmp_re > 127)
// {
// tmp_re = 127;
// }
// if (tmp_re < -128)
// {
// tmp_re = -128;
// }
// if (tmp_im > 127)
// {
// tmp_im = 127;
// }
// if (tmp_im < -128)
// {
// tmp_im = -128;
// }
// d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(tmp_re), static_cast<int>(tmp_im));
//
} }
// // debug
// char filename2[25];
// FILE *fid2;
// sprintf(filename2,"fft_gal_prn%d_norm.txt", PRN);
// fid2 = fopen(filename2, "w");
// for (unsigned int kk=0;kk< nsamples_total; kk++)
// {
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real());
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag());
// }
// fclose(fid2);
} }
// for (unsigned int PRN = 1; PRN <= GALILEO_E1_NUMBER_OF_CODES; PRN++)
// {
// // debug
// char filename2[25];
// FILE *fid2;
// sprintf(filename2,"fft_gal_prn%d_norm_last.txt", PRN);
// fid2 = fopen(filename2, "w");
// for (unsigned int kk=0;kk< nsamples_total; kk++)
// {
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real());
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag());
// }
// fclose(fid2);
// }
//acq_parameters
acq_parameters.all_fft_codes = d_all_fft_codes_; acq_parameters.all_fft_codes = d_all_fft_codes_;
// reference for the FPGA FFT-IFFT attenuation factor
acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 14);
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
channel_ = 0;
doppler_step_ = 0;
gnss_synchro_ = nullptr;
// temporary buffers that we can delete // temporary buffers that we can delete
delete[] code; delete[] code;
delete fft_if; delete fft_if;
delete[] fft_codes_padded; 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_ = nullptr;
//printf("top acq constructor end\n");
} }
GalileoE1PcpsAmbiguousAcquisitionFpga::~GalileoE1PcpsAmbiguousAcquisitionFpga() GalileoE1PcpsAmbiguousAcquisitionFpga::~GalileoE1PcpsAmbiguousAcquisitionFpga()
{ {
//printf("top acq destructor start\n");
//delete[] code_;
delete[] d_all_fft_codes_; delete[] d_all_fft_codes_;
//printf("top acq destructor end\n");
} }
void GalileoE1PcpsAmbiguousAcquisitionFpga::stop_acquisition() void GalileoE1PcpsAmbiguousAcquisitionFpga::stop_acquisition()
{ {
// this command causes the SW to reset the HW.
acquisition_fpga_->reset_acquisition();
} }
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_channel(unsigned int channel) void GalileoE1PcpsAmbiguousAcquisitionFpga::set_channel(unsigned int channel)
{ {
//printf("top acq set channel start\n");
channel_ = channel; channel_ = channel;
acquisition_fpga_->set_channel(channel_); acquisition_fpga_->set_channel(channel_);
//printf("top acq set channel end\n");
} }
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_threshold(float threshold) void GalileoE1PcpsAmbiguousAcquisitionFpga::set_threshold(float threshold)
{ {
//printf("top acq set threshold start\n");
// 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; DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold;
acquisition_fpga_->set_threshold(threshold); acquisition_fpga_->set_threshold(threshold);
// acquisition_fpga_->set_threshold(threshold_);
//printf("top acq set threshold end\n");
} }
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_max(unsigned int doppler_max) void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_max(unsigned int doppler_max)
{ {
//printf("top acq set doppler max start\n");
doppler_max_ = doppler_max; doppler_max_ = doppler_max;
acquisition_fpga_->set_doppler_max(doppler_max_); acquisition_fpga_->set_doppler_max(doppler_max_);
//printf("top acq set doppler max end\n");
} }
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_step(unsigned int doppler_step) void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
{ {
//printf("top acq set doppler step start\n");
doppler_step_ = doppler_step; doppler_step_ = doppler_step;
acquisition_fpga_->set_doppler_step(doppler_step_); acquisition_fpga_->set_doppler_step(doppler_step_);
//printf("top acq set doppler step end\n");
} }
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) void GalileoE1PcpsAmbiguousAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
{ {
//printf("top acq set gnss synchro start\n");
gnss_synchro_ = gnss_synchro; gnss_synchro_ = gnss_synchro;
acquisition_fpga_->set_gnss_synchro(gnss_synchro_); acquisition_fpga_->set_gnss_synchro(gnss_synchro_);
//printf("top acq set gnss synchro end\n");
} }
signed int GalileoE1PcpsAmbiguousAcquisitionFpga::mag() signed int GalileoE1PcpsAmbiguousAcquisitionFpga::mag()
{ {
// printf("top acq mag start\n");
return acquisition_fpga_->mag(); return acquisition_fpga_->mag();
//printf("top acq mag end\n");
} }
void GalileoE1PcpsAmbiguousAcquisitionFpga::init() void GalileoE1PcpsAmbiguousAcquisitionFpga::init()
{ {
// printf("top acq init start\n");
acquisition_fpga_->init(); acquisition_fpga_->init();
// printf("top acq init end\n");
//set_local_code();
} }
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_local_code() void GalileoE1PcpsAmbiguousAcquisitionFpga::set_local_code()
{ {
// printf("top acq set local code start\n");
// 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(); acquisition_fpga_->set_local_code();
// delete[] code;
// printf("top acq set local code end\n");
} }
void GalileoE1PcpsAmbiguousAcquisitionFpga::reset() void GalileoE1PcpsAmbiguousAcquisitionFpga::reset()
{ {
// printf("top acq reset start\n"); // This command starts the acquisition process
acquisition_fpga_->set_active(true); acquisition_fpga_->set_active(true);
// printf("top acq reset end\n");
} }
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_state(int state) void GalileoE1PcpsAmbiguousAcquisitionFpga::set_state(int state)
{ {
// printf("top acq set state start\n");
acquisition_fpga_->set_state(state); acquisition_fpga_->set_state(state);
// printf("top acq set state end\n");
} }
//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) void GalileoE1PcpsAmbiguousAcquisitionFpga::connect(gr::top_block_sptr top_block)
{ {
// printf("top acq connect\n"); if (top_block)
// if (item_type_.compare("gr_complex") == 0) { /* top_block is not null */
// { };
// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); // Nothing to connect
// }
// 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) void GalileoE1PcpsAmbiguousAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
{ {
// if (item_type_.compare("gr_complex") == 0) if (top_block)
// { { /* top_block is not null */
// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); };
// } // Nothing to disconnect
// 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
// printf("top acq disconnect\n");
} }
gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_left_block() gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_left_block()
{ {
// printf("top acq get left block start\n");
// 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; return nullptr;
// }
// printf("top acq get left block end\n");
} }
gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_right_block() gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_right_block()
{ {
// printf("top acq get right block start\n");
return acquisition_fpga_; return acquisition_fpga_;
// printf("top acq get right block end\n");
} }

View File

@ -1,12 +1,12 @@
/*! /*!
* \file galileo_e1_pcps_ambiguous_acquisition.h * \file galileo_e1_pcps_ambiguous_acquisition_fpga.h
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Galileo E1 Signals * Galileo E1 Signals
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com * \author Marc Majoral, 2019. mmajoral(at)cttc.es
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -60,22 +60,19 @@ public:
inline std::string role() override inline std::string role() override
{ {
// printf("top acq role\n");
return role_; return role_;
} }
/*! /*!
* \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition" * \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga"
*/ */
inline std::string implementation() override inline std::string implementation() override
{ {
// printf("top acq implementation\n");
return "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga"; return "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga";
} }
size_t item_size() override size_t item_size() override
{ {
// printf("top acq item size\n");
size_t item_size = sizeof(lv_16sc_t); size_t item_size = sizeof(lv_16sc_t);
return item_size; return item_size;
} }
@ -146,37 +143,25 @@ public:
private: private:
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
//pcps_acquisition_sptr acquisition_;
pcps_acquisition_fpga_sptr acquisition_fpga_; pcps_acquisition_fpga_sptr acquisition_fpga_;
gr::blocks::stream_to_vector::sptr stream_to_vector_; gr::blocks::stream_to_vector::sptr stream_to_vector_;
gr::blocks::float_to_complex::sptr float_to_complex_; gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_; 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 bit_transition_flag_;
bool use_CFAR_algorithm_flag_; bool use_CFAR_algorithm_flag_;
bool acquire_pilot_; bool acquire_pilot_;
unsigned int channel_; uint32_t channel_;
//float threshold_; uint32_t doppler_max_;
unsigned int doppler_max_; uint32_t doppler_step_;
unsigned int doppler_step_; uint32_t max_dwells_;
//unsigned int sampled_ms_;
unsigned int max_dwells_;
//long fs_in_;
//long if_;
bool dump_; bool dump_;
bool blocking_; bool blocking_;
std::string dump_filename_; std::string dump_filename_;
//std::complex<float>* code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_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 lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts
}; };

View File

@ -1,11 +1,12 @@
/*! /*!
* \file galileo_e5a_pcps_acquisition.cc * \file galileo_e5a_pcps_acquisition_fpga.cc
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Galileo E5a data and pilot Signals * Galileo E5a data and pilot Signals for the FPGA
* \author Antonio Ramos, 2018. antonio.ramos(at)cttc.es * \author Marc Majoral, 2019. mmajoral(at)cttc.es
*
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -48,39 +49,27 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
in_streams_(in_streams), in_streams_(in_streams),
out_streams_(out_streams) out_streams_(out_streams)
{ {
//printf("creating the E5A acquisition");
pcpsconf_fpga_t acq_parameters; pcpsconf_fpga_t acq_parameters;
configuration_ = configuration; configuration_ = configuration;
std::string default_item_type = "gr_complex"; std::string default_dump_filename = "../data/acquisition.dat";
std::string default_dump_filename = "./acquisition.mat";
DLOG(INFO) << "Role " << role; DLOG(INFO) << "Role " << role;
//item_type_ = configuration_->property(role + ".item_type", default_item_type);
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000);
int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
float downsampling_factor = configuration_->property(role + ".downsampling_factor", 1.0);
acq_parameters.downsampling_factor = downsampling_factor;
fs_in = fs_in / downsampling_factor;
acq_parameters.fs_in = fs_in; acq_parameters.fs_in = fs_in;
//acq_parameters.freq = 0;
//dump_ = configuration_->property(role + ".dump", false);
//acq_parameters.dump = dump_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000); doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_; acq_parameters.doppler_max = doppler_max_;
unsigned int sampled_ms = 1;
//max_dwells_ = configuration_->property(role + ".max_dwells", 1); uint32_t sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
//acq_parameters.max_dwells = max_dwells_; acq_parameters.sampled_ms = sampled_ms;
//dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
//acq_parameters.dump_filename = dump_filename_;
//bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
//acq_parameters.bit_transition_flag = bit_transition_flag_;
//use_CFAR_ = configuration_->property(role + ".use_CFAR_algorithm", false);
//acq_parameters.use_CFAR_algorithm_flag = use_CFAR_;
//blocking_ = configuration_->property(role + ".blocking", true);
//acq_parameters.blocking = blocking_;
//--- Find number of samples per spreading code (1ms)-------------------------
acq_pilot_ = configuration_->property(role + ".acquire_pilot", false); acq_pilot_ = configuration_->property(role + ".acquire_pilot", false);
acq_iq_ = configuration_->property(role + ".acquire_iq", false); acq_iq_ = configuration_->property(role + ".acquire_iq", false);
@ -89,14 +78,13 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
acq_pilot_ = false; acq_pilot_ = false;
} }
auto code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / GALILEO_E5A_CODE_CHIP_RATE_HZ * static_cast<double>(GALILEO_E5A_CODE_LENGTH_CHIPS))); auto code_length = static_cast<uint32_t>(std::round(static_cast<double>(fs_in) / GALILEO_E5A_CODE_CHIP_RATE_HZ * static_cast<double>(GALILEO_E5A_CODE_LENGTH_CHIPS)));
acq_parameters.code_length = code_length; acq_parameters.code_length = code_length;
// The FPGA can only use FFT lengths that are a power of two. // The FPGA can only use FFT lengths that are a power of two.
float nbits = ceilf(log2f((float)code_length)); float nbits = ceilf(log2f((float)code_length * 2));
unsigned int nsamples_total = pow(2, nbits); uint32_t nsamples_total = pow(2, nbits);
unsigned int vector_length = nsamples_total; uint32_t select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1);
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1);
//printf("select_queue_Fpga = %d\n", select_queue_Fpga);
acq_parameters.select_queue_Fpga = select_queue_Fpga; acq_parameters.select_queue_Fpga = select_queue_Fpga;
std::string default_device_name = "/dev/uio0"; std::string default_device_name = "/dev/uio0";
std::string device_name = configuration_->property(role + ".devicename", default_device_name); std::string device_name = configuration_->property(role + ".devicename", default_device_name);
@ -104,9 +92,9 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
acq_parameters.samples_per_ms = nsamples_total / sampled_ms; acq_parameters.samples_per_ms = nsamples_total / sampled_ms;
acq_parameters.samples_per_code = nsamples_total; acq_parameters.samples_per_code = nsamples_total;
//vector_length_ = code_length_ * sampled_ms_; acq_parameters.excludelimit = static_cast<uint32_t>(ceil((1.0 / GALILEO_E5A_CODE_CHIP_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
// compute all the GALILEO E5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time // compute all the GALILEO E5 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time
// a channel is assigned) // a channel is assigned)
auto* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT auto* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT
auto* code = new std::complex<float>[nsamples_total]; // buffer for the local code auto* code = new std::complex<float>[nsamples_total]; // buffer for the local code
@ -114,12 +102,8 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
d_all_fft_codes_ = new lv_16sc_t[nsamples_total * GALILEO_E5A_NUMBER_OF_CODES]; // memory containing all the possible fft codes for PRN 0 to 32 d_all_fft_codes_ = new lv_16sc_t[nsamples_total * GALILEO_E5A_NUMBER_OF_CODES]; // memory containing all the possible fft codes for PRN 0 to 32
float max; // temporary maxima search float max; // temporary maxima search
//printf("creating the E5A acquisition CONT"); for (uint32_t PRN = 1; PRN <= GALILEO_E5A_NUMBER_OF_CODES; PRN++)
//printf("nsamples_total = %d\n", nsamples_total);
for (unsigned int PRN = 1; PRN <= GALILEO_E5A_NUMBER_OF_CODES; PRN++)
{ {
// gr_complex* code = new gr_complex[code_length_];
char signal_[3]; char signal_[3];
if (acq_iq_) if (acq_iq_)
@ -135,14 +119,17 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
strcpy(signal_, "5I"); strcpy(signal_, "5I");
} }
galileo_e5_a_code_gen_complex_sampled(code, signal_, PRN, fs_in, 0); galileo_e5_a_code_gen_complex_sampled(code, signal_, PRN, fs_in, 0);
for (uint32_t s = code_length; s < 2 * code_length; s++)
{
code[s] = code[s - code_length];
}
// fill in zero padding // fill in zero padding
for (int s = code_length; s < nsamples_total; s++) for (uint32_t s = 2 * code_length; s < nsamples_total; s++)
{ {
code[s] = std::complex<float>(0.0, 0.0); code[s] = std::complex<float>(0.0, 0.0);
//code[s] = 0;
} }
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
@ -150,7 +137,7 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
max = 0; // initialize maximum value max = 0; // initialize maximum value
for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima
{ {
if (std::abs(fft_codes_padded[i].real()) > max) if (std::abs(fft_codes_padded[i].real()) > max)
{ {
@ -161,101 +148,55 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
max = std::abs(fft_codes_padded[i].imag()); 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 for (uint32_t 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, 15) - 1) / max)), d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, 9) - 1) / max)),
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max)));
} }
} }
acq_parameters.all_fft_codes = d_all_fft_codes_; acq_parameters.all_fft_codes = d_all_fft_codes_;
// reference for the FPGA FFT-IFFT attenuation factor
acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 14);
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
channel_ = 0;
doppler_step_ = 0;
gnss_synchro_ = nullptr;
// temporary buffers that we can delete // temporary buffers that we can delete
delete[] code; delete[] code;
delete fft_if; delete fft_if;
delete[] fft_codes_padded; delete[] fft_codes_padded;
//code_ = new gr_complex[vector_length_];
// if (item_type_.compare("gr_complex") == 0)
// {
// item_size_ = sizeof(gr_complex);
// }
// else if (item_type_.compare("cshort") == 0)
// {
// item_size_ = sizeof(lv_16sc_t);
// }
// else
// {
// item_size_ = sizeof(gr_complex);
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
// }
//acq_parameters.it_size = item_size_;
//acq_parameters.samples_per_code = code_length_;
//acq_parameters.samples_per_ms = code_length_;
//acq_parameters.sampled_ms = sampled_ms_;
//acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
//acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
//acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
//acquisition_ = pcps_make_acquisition(acq_parameters);
//acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
//DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
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_);
channel_ = 0;
//threshold_ = 0.0;
doppler_step_ = 0;
gnss_synchro_ = nullptr;
//printf("creating the E5A acquisition end");
} }
GalileoE5aPcpsAcquisitionFpga::~GalileoE5aPcpsAcquisitionFpga() GalileoE5aPcpsAcquisitionFpga::~GalileoE5aPcpsAcquisitionFpga()
{ {
//delete[] code_;
delete[] d_all_fft_codes_; delete[] d_all_fft_codes_;
} }
void GalileoE5aPcpsAcquisitionFpga::stop_acquisition() void GalileoE5aPcpsAcquisitionFpga::stop_acquisition()
{ {
// this command causes the SW to reset the HW.
acquisition_fpga_->reset_acquisition();
} }
void GalileoE5aPcpsAcquisitionFpga::set_channel(unsigned int channel) void GalileoE5aPcpsAcquisitionFpga::set_channel(unsigned int channel)
{ {
channel_ = channel; channel_ = channel;
//acquisition_->set_channel(channel_);
acquisition_fpga_->set_channel(channel_); acquisition_fpga_->set_channel(channel_);
} }
void GalileoE5aPcpsAcquisitionFpga::set_threshold(float threshold) void GalileoE5aPcpsAcquisitionFpga::set_threshold(float threshold)
{ {
// float pfa = configuration_->property(role_ + std::to_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; DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold;
//acquisition_->set_threshold(threshold_);
acquisition_fpga_->set_threshold(threshold); acquisition_fpga_->set_threshold(threshold);
} }
@ -263,7 +204,6 @@ void GalileoE5aPcpsAcquisitionFpga::set_threshold(float threshold)
void GalileoE5aPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) void GalileoE5aPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max)
{ {
doppler_max_ = doppler_max; doppler_max_ = doppler_max;
//acquisition_->set_doppler_max(doppler_max_);
acquisition_fpga_->set_doppler_max(doppler_max_); acquisition_fpga_->set_doppler_max(doppler_max_);
} }
@ -271,7 +211,6 @@ void GalileoE5aPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max)
void GalileoE5aPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) void GalileoE5aPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
{ {
doppler_step_ = doppler_step; doppler_step_ = doppler_step;
//acquisition_->set_doppler_step(doppler_step_);
acquisition_fpga_->set_doppler_step(doppler_step_); acquisition_fpga_->set_doppler_step(doppler_step_);
} }
@ -279,132 +218,65 @@ void GalileoE5aPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
void GalileoE5aPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) void GalileoE5aPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
{ {
gnss_synchro_ = gnss_synchro; gnss_synchro_ = gnss_synchro;
//acquisition_->set_gnss_synchro(gnss_synchro_);
acquisition_fpga_->set_gnss_synchro(gnss_synchro_); acquisition_fpga_->set_gnss_synchro(gnss_synchro_);
} }
signed int GalileoE5aPcpsAcquisitionFpga::mag() signed int GalileoE5aPcpsAcquisitionFpga::mag()
{ {
//return acquisition_->mag();
return acquisition_fpga_->mag(); return acquisition_fpga_->mag();
} }
void GalileoE5aPcpsAcquisitionFpga::init() void GalileoE5aPcpsAcquisitionFpga::init()
{ {
//acquisition_->init();
acquisition_fpga_->init(); acquisition_fpga_->init();
} }
void GalileoE5aPcpsAcquisitionFpga::set_local_code() void GalileoE5aPcpsAcquisitionFpga::set_local_code()
{ {
// gr_complex* code = new gr_complex[code_length_];
// char signal_[3];
//
// if (acq_iq_)
// {
// strcpy(signal_, "5X");
// }
// else if (acq_pilot_)
// {
// strcpy(signal_, "5Q");
// }
// else
// {
// strcpy(signal_, "5I");
// }
//
// galileo_e5_a_code_gen_complex_sampled(code, signal_, gnss_synchro_->PRN, fs_in_, 0);
//
// for (unsigned int i = 0; i < sampled_ms_; i++)
// {
// memcpy(code_ + (i * code_length_), code, sizeof(gr_complex) * code_length_);
// }
//acquisition_->set_local_code(code_);
acquisition_fpga_->set_local_code(); acquisition_fpga_->set_local_code();
// delete[] code;
} }
void GalileoE5aPcpsAcquisitionFpga::reset() void GalileoE5aPcpsAcquisitionFpga::reset()
{ {
//acquisition_->set_active(true);
acquisition_fpga_->set_active(true); acquisition_fpga_->set_active(true);
} }
//float GalileoE5aPcpsAcquisitionFpga::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 GalileoE5aPcpsAcquisitionFpga::set_state(int state) void GalileoE5aPcpsAcquisitionFpga::set_state(int state)
{ {
//acquisition_->set_state(state);
acquisition_fpga_->set_state(state); acquisition_fpga_->set_state(state);
} }
void GalileoE5aPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) void GalileoE5aPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block)
{ {
// if (item_type_.compare("gr_complex") == 0) if (top_block)
// { { /* top_block is not null */
// top_block->connect(stream_to_vector_, 0, acquisition_, 0); };
// } // Nothing to connect
// else if (item_type_.compare("cshort") == 0)
// {
// top_block->connect(stream_to_vector_, 0, acquisition_, 0);
// }
// else
// {
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
// }
} }
void GalileoE5aPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) void GalileoE5aPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
{ {
// if (item_type_.compare("gr_complex") == 0) if (top_block)
// { { /* top_block is not null */
// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); };
// } // Nothing to disconnect
// else if (item_type_.compare("cshort") == 0)
// {
// top_block->disconnect(stream_to_vector_, 0, acquisition_, 0);
// }
// else
// {
// LOG(WARNING) << item_type_ << " unknown acquisition item type";
// }
} }
gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_left_block() gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_left_block()
{ {
//return stream_to_vector_;
return nullptr; return nullptr;
} }
gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_right_block() gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_right_block()
{ {
//return acquisition_;
return acquisition_fpga_; return acquisition_fpga_;
} }

View File

@ -1,11 +1,12 @@
/*! /*!
* \file galileo_e5a_pcps_acquisition.h * \file galileo_e5a_pcps_acquisition_fpga.h
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Galileo E5a data and pilot Signals * Galileo E5a data and pilot Signals for the FPGA
* \author Antonio Ramos, 2018. antonio.ramos(at)cttc.es * \author Marc Majoral, 2019. mmajoral(at)cttc.es
*
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -28,8 +29,8 @@
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
#ifndef GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ #ifndef GNSS_SDR_GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_
#define GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ #define GNSS_SDR_GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_
#include "acquisition_interface.h" #include "acquisition_interface.h"
@ -56,6 +57,9 @@ public:
return role_; return role_;
} }
/*!
* \brief Returns "Galileo_E5a_Pcps_Acquisition_Fpga"
*/
inline std::string implementation() override inline std::string implementation() override
{ {
return "Galileo_E5a_Pcps_Acquisition_Fpga"; return "Galileo_E5a_Pcps_Acquisition_Fpga";
@ -125,16 +129,22 @@ public:
*/ */
void set_state(int state) override; void set_state(int state) override;
/*!
* \brief This function is only used in the unit tests
*/
void set_single_doppler_flag(unsigned int single_doppler_flag);
/*! /*!
* \brief Stop running acquisition * \brief Stop running acquisition
*/ */
void stop_acquisition() override; void stop_acquisition() override;
/*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation
*/
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private: private:
//float calculate_threshold(float pfa);
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
pcps_acquisition_fpga_sptr acquisition_fpga_; pcps_acquisition_fpga_sptr acquisition_fpga_;
@ -153,31 +163,25 @@ private:
bool blocking_; bool blocking_;
bool acq_iq_; bool acq_iq_;
unsigned int vector_length_; uint32_t vector_length_;
unsigned int code_length_; uint32_t code_length_;
unsigned int channel_; uint32_t channel_;
unsigned int doppler_max_; uint32_t doppler_max_;
unsigned int doppler_step_; uint32_t doppler_step_;
unsigned int sampled_ms_; uint32_t sampled_ms_;
unsigned int max_dwells_; uint32_t max_dwells_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
int64_t fs_in_; int64_t fs_in_;
float threshold_; float threshold_;
/*
std::complex<float>* codeI_;
std::complex<float>* codeQ_;
*/
gr_complex* code_; gr_complex* code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
// extra for the FPGA
lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts
}; };
#endif /* GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ */
#endif /* GNSS_SDR_GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ */

View File

@ -1,17 +1,15 @@
/*! /*!
* \file gps_l1_ca_pcps_acquisition_fpga.cc * \file gps_l1_ca_pcps_acquisition_fpga.cc
* \brief Adapts a PCPS acquisition block to an FPGA AcquisitionInterface * \brief Adapts a PCPS acquisition block to an AcquisitionInterface
* for GPS L1 C/A signals * for GPS L1 C/A signals for the FPGA
* \authors <ul> * \authors <ul>
* <li> Marc Majoral, 2018. mmajoral(at)cttc.es * <li> Marc Majoral, 2019. mmajoral(at)cttc.es
* <li> Javier Arribas, 2011. jarribas(at)cttc.es * <li> Javier Arribas, 2019. jarribas(at)cttc.es
* <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
* <li> Marc Molina, 2013. marc.molina.pena(at)gmail.com
* </ul> * </ul>
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -59,72 +57,67 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
{ {
pcpsconf_fpga_t acq_parameters; pcpsconf_fpga_t acq_parameters;
configuration_ = configuration; configuration_ = configuration;
std::string default_item_type = "gr_complex"; std::string default_item_type = "cshort";
DLOG(INFO) << "role " << role; DLOG(INFO) << "role " << role;
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
//fs_in = fs_in/2.0; // downampling filter
//printf("####### DEBUG Acq: fs_in = %d\n", fs_in); float downsampling_factor = configuration_->property(role + ".downsampling_factor", 4.0);
acq_parameters.downsampling_factor = downsampling_factor;
fs_in = fs_in / downsampling_factor;
acq_parameters.fs_in = fs_in; acq_parameters.fs_in = fs_in;
acq_parameters.samples_per_code = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
doppler_max_ = configuration_->property(role + ".doppler_max", 5000); doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_; acq_parameters.doppler_max = doppler_max_;
unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1); uint32_t sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms; acq_parameters.sampled_ms = sampled_ms;
auto code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); auto code_length = static_cast<uint32_t>(std::round(static_cast<double>(fs_in) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)));
acq_parameters.code_length = code_length; acq_parameters.code_length = code_length;
// The FPGA can only use FFT lengths that are a power of two. // The FPGA can only use FFT lengths that are a power of two.
float nbits = ceilf(log2f((float)code_length)); float nbits = ceilf(log2f((float)code_length * 2));
unsigned int nsamples_total = pow(2, nbits); uint32_t nsamples_total = pow(2, nbits);
unsigned int vector_length = nsamples_total; uint32_t select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
acq_parameters.select_queue_Fpga = select_queue_Fpga; acq_parameters.select_queue_Fpga = select_queue_Fpga;
std::string default_device_name = "/dev/uio0"; std::string default_device_name = "/dev/uio0";
std::string device_name = configuration_->property(role + ".devicename", default_device_name); std::string device_name = configuration_->property(role + ".devicename", default_device_name);
acq_parameters.device_name = device_name; acq_parameters.device_name = device_name;
acq_parameters.samples_per_ms = nsamples_total / sampled_ms; acq_parameters.samples_per_ms = nsamples_total / sampled_ms;
acq_parameters.samples_per_code = nsamples_total; acq_parameters.samples_per_code = nsamples_total;
acq_parameters.excludelimit = static_cast<uint32_t>(std::round(static_cast<double>(fs_in) / GPS_L1_CA_CODE_RATE_HZ));
// 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 // 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) // a channel is assigned)
auto* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT auto* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT
// allocate memory to compute all the PRNs and compute all the possible codes // allocate memory to compute all the PRNs and compute all the possible codes
auto* code = new std::complex<float>[nsamples_total]; // buffer for the local code auto* code = new std::complex<float>[nsamples_total]; // buffer for the local code
auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); auto* 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 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 float max; // temporary maxima search
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++)
{ {
gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code
for (uint32_t s = code_length; s < 2 * code_length; s++)
{
code[s] = code[s - code_length];
}
// fill in zero padding // fill in zero padding
for (int s = code_length; s < nsamples_total; s++) for (uint32_t s = 2 * code_length; s < nsamples_total; s++)
{ {
code[s] = std::complex<float>(0.0, 0.0); code[s] = std::complex<float>(0.0, 0.0);
//code[s] = 0;
} }
int offset = 0;
memcpy(fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
fft_if->execute(); // Run the FFT of local code fft_if->execute(); // Run the FFT of local code
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
// // debug
// char filename[25];
// FILE *fid;
// sprintf(filename,"fft_gps_prn%d.txt", PRN);
// fid = fopen(filename, "w");
// for (unsigned int kk=0;kk< nsamples_total; kk++)
// {
// fprintf(fid, "%f\n", fft_codes_padded[kk].real());
// fprintf(fid, "%f\n", fft_codes_padded[kk].imag());
// }
// fclose(fid);
max = 0; // initialize maximum value max = 0; // initialize maximum value
for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima
{ {
if (std::abs(fft_codes_padded[i].real()) > max) if (std::abs(fft_codes_padded[i].real()) > max)
{ {
@ -135,39 +128,18 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
max = std::abs(fft_codes_padded[i].imag()); 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 for (uint32_t 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(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, 9) - 1) / max)),
// static_cast<int>(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max)));
//d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(16*floor(fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)),
// static_cast<int>(16*floor(fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max)));
//d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)),
// static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max)));
d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)),
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max)));
} }
//// // debug
// char filename2[25];
// FILE *fid2;
// sprintf(filename2,"fft_gps_prn%d_norm_new.txt", PRN);
// fid2 = fopen(filename2, "w");
// for (unsigned int kk=0;kk< nsamples_total; kk++)
// {
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real());
// fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag());
// }
// fclose(fid2);
} }
//acq_parameters //acq_parameters
acq_parameters.all_fft_codes = d_all_fft_codes_; acq_parameters.all_fft_codes = d_all_fft_codes_;
// temporary buffers that we can delete // reference for the FPGA FFT-IFFT attenuation factor
delete[] code; acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 14);
delete fft_if;
delete[] fft_codes_padded;
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
@ -175,6 +147,11 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
channel_ = 0; channel_ = 0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
// temporary buffers that we can delete
delete[] code;
delete fft_if;
delete[] fft_codes_padded;
} }
@ -186,6 +163,8 @@ GpsL1CaPcpsAcquisitionFpga::~GpsL1CaPcpsAcquisitionFpga()
void GpsL1CaPcpsAcquisitionFpga::stop_acquisition() void GpsL1CaPcpsAcquisitionFpga::stop_acquisition()
{ {
// this command causes the SW to reset the HW.
acquisition_fpga_->reset_acquisition();
} }
@ -198,8 +177,6 @@ void GpsL1CaPcpsAcquisitionFpga::set_channel(unsigned int channel)
void GpsL1CaPcpsAcquisitionFpga::set_threshold(float threshold) 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; DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold;
acquisition_fpga_->set_threshold(threshold); acquisition_fpga_->set_threshold(threshold);
} }
@ -246,6 +223,7 @@ void GpsL1CaPcpsAcquisitionFpga::set_local_code()
void GpsL1CaPcpsAcquisitionFpga::reset() void GpsL1CaPcpsAcquisitionFpga::reset()
{ {
// this function starts the acquisition process
acquisition_fpga_->set_active(true); acquisition_fpga_->set_active(true);
} }
@ -255,15 +233,22 @@ void GpsL1CaPcpsAcquisitionFpga::set_state(int state)
acquisition_fpga_->set_state(state); acquisition_fpga_->set_state(state);
} }
void GpsL1CaPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) void GpsL1CaPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block)
{ {
// nothing to connect if (top_block)
{ /* top_block is not null */
};
// Nothing to connect
} }
void GpsL1CaPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) void GpsL1CaPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
{ {
// nothing to disconnect if (top_block)
{ /* top_block is not null */
};
// Nothing to disconnect
} }

View File

@ -1,17 +1,15 @@
/*! /*!
* \file gps_l1_ca_pcps_acquisition_fpga.h * \file gps_l1_ca_pcps_acquisition_fpga.h
* \brief Adapts a PCPS acquisition block that uses the FPGA to * \brief Adapts a PCPS acquisition block to an AcquisitionInterface
* an AcquisitionInterface for GPS L1 C/A signals * for GPS L1 C/A signals for the FPGA
* \authors <ul> * \authors <ul>
* <li> Marc Majoral, 2018. mmajoral(at)cttc.es * <li> Marc Majoral, 2019. mmajoral(at)cttc.es
* <li> Javier Arribas, 2011. jarribas(at)cttc.es * <li> Javier Arribas, 2019. jarribas(at)cttc.es
* <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
* <li> Marc Molina, 2013. marc.molina.pena(at)gmail.com
* </ul> * </ul>
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -65,7 +63,7 @@ public:
} }
/*! /*!
* \brief Returns "GPS_L1_CA_PCPS_Acquisition" * \brief Returns "GPS_L1_CA_PCPS_Acquisition_Fpga"
*/ */
inline std::string implementation() override inline std::string implementation() override
{ {
@ -145,9 +143,9 @@ public:
private: private:
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
pcps_acquisition_fpga_sptr acquisition_fpga_; pcps_acquisition_fpga_sptr acquisition_fpga_;
unsigned int channel_; uint32_t channel_;
unsigned int doppler_max_; uint32_t doppler_max_;
unsigned int doppler_step_; uint32_t doppler_step_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;

View File

@ -375,6 +375,8 @@ gr::basic_block_sptr GpsL2MPcpsAcquisition::get_right_block()
{ {
return acquisition_; return acquisition_;
} }
void GpsL2MPcpsAcquisition::set_resampler_latency(uint32_t latency_samples) void GpsL2MPcpsAcquisition::set_resampler_latency(uint32_t latency_samples)
{ {
acquisition_->set_resampler_latency(latency_samples); acquisition_->set_resampler_latency(latency_samples);

View File

@ -1,14 +1,15 @@
/*! /*!
* \file gps_l5i pcps_acquisition.cc * \file gps_l5i pcps_acquisition_fpga.cc
* \brief Adapts a PCPS acquisition block to an Acquisition Interface for * \brief Adapts a PCPS acquisition block to an Acquisition Interface for
* GPS L5i signals * GPS L5i signals for the FPGA
* \authors <ul> * \authors <ul>
* <li> Javier Arribas, 2017. jarribas(at)cttc.es * <li> Marc Majoral, 2019. mmajoral(at)cttc.es
* <li> Javier Arribas, 2019. jarribas(at)cttc.es
* </ul> * </ul>
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -52,87 +53,71 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga(
in_streams_(in_streams), in_streams_(in_streams),
out_streams_(out_streams) out_streams_(out_streams)
{ {
//printf("L5 ACQ CLASS CREATED\n");
pcpsconf_fpga_t acq_parameters; pcpsconf_fpga_t acq_parameters;
configuration_ = configuration; configuration_ = configuration;
std::string default_item_type = "gr_complex"; std::string default_dump_filename = "./data/acquisition.dat";
std::string default_dump_filename = "./acquisition.mat";
LOG(INFO) << "role " << role; LOG(INFO) << "role " << role;
//item_type_ = configuration_->property(role + ".item_type", default_item_type);
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
float downsampling_factor = configuration_->property(role + ".downsampling_factor", 1.0);
acq_parameters.downsampling_factor = downsampling_factor;
fs_in = fs_in / downsampling_factor;
acq_parameters.fs_in = fs_in; 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); doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_; acq_parameters.doppler_max = doppler_max_;
//acq_parameters.sampled_ms = 1; uint32_t sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms; acq_parameters.sampled_ms = sampled_ms;
//printf("L5 ACQ CLASS MID 0\n");
//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_;
//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 ------------------------- //--- Find number of samples per spreading code -------------------------
auto code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (GPS_L5I_CODE_RATE_HZ / static_cast<double>(GPS_L5I_CODE_LENGTH_CHIPS)))); auto code_length = static_cast<uint32_t>(std::round(static_cast<double>(fs_in) / (GPS_L5I_CODE_RATE_HZ / static_cast<double>(GPS_L5I_CODE_LENGTH_CHIPS))));
acq_parameters.code_length = code_length; acq_parameters.code_length = code_length;
// The FPGA can only use FFT lengths that are a power of two. // The FPGA can only use FFT lengths that are a power of two.
float nbits = ceilf(log2f((float)code_length)); float nbits = ceilf(log2f((float)code_length * 2));
unsigned int nsamples_total = pow(2, nbits); uint32_t nsamples_total = pow(2, nbits);
unsigned int vector_length = nsamples_total; uint32_t select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1);
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1);
acq_parameters.select_queue_Fpga = select_queue_Fpga; acq_parameters.select_queue_Fpga = select_queue_Fpga;
std::string default_device_name = "/dev/uio0"; std::string default_device_name = "/dev/uio0";
std::string device_name = configuration_->property(role + ".devicename", default_device_name); std::string device_name = configuration_->property(role + ".devicename", default_device_name);
acq_parameters.device_name = 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; acq_parameters.samples_per_code = nsamples_total;
//printf("L5 ACQ CLASS MID 01\n");
acq_parameters.excludelimit = static_cast<uint32_t>(ceil((1.0 / GPS_L5I_CODE_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
// compute all the GPS L5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time // compute all the GPS L5 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) // a channel is assigned)
auto* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT auto* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT
//printf("L5 ACQ CLASS MID 02\n"); auto* code = new gr_complex[nsamples_total];
auto* code = new gr_complex[vector_length];
//printf("L5 ACQ CLASS MID 03\n");
auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
//printf("L5 ACQ CLASS MID 04\n");
d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32 d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32
//printf("L5 ACQ CLASS MID 1 vector_length = %d\n", vector_length);
float max; // temporary maxima search float max; // temporary maxima search
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++)
{ {
//printf("L5 ACQ CLASS processing PRN = %d\n", PRN);
gps_l5i_code_gen_complex_sampled(code, PRN, fs_in); gps_l5i_code_gen_complex_sampled(code, PRN, fs_in);
//printf("L5 ACQ CLASS processing PRN = %d (cont) \n", PRN);
// fill in zero padding for (uint32_t s = code_length; s < 2 * code_length; s++)
for (int s = code_length; s < nsamples_total; s++)
{ {
code[s] = code[s - code_length];
}
for (uint32_t s = 2 * code_length; s < nsamples_total; s++)
{
// fill in zero padding
code[s] = std::complex<float>(0.0, 0.0); code[s] = std::complex<float>(0.0, 0.0);
//code[s] = 0;
} }
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
fft_if->execute(); // Run the FFT of local code fft_if->execute(); // Run the FFT of local code
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
max = 0; // initialize maximum value max = 0; // initialize maximum value
for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima
{ {
if (std::abs(fft_codes_padded[i].real()) > max) if (std::abs(fft_codes_padded[i].real()) > max)
{ {
@ -143,73 +128,30 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga(
max = std::abs(fft_codes_padded[i].imag()); 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 for (uint32_t 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(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, 9) - 1) / max)),
// static_cast<int>(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max)));
//d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(16*floor(fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)),
// static_cast<int>(16*floor(fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max)));
//d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)),
// static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max)));
d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)),
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max)));
} }
} }
//printf("L5 ACQ CLASS MID 2\n");
//acq_parameters //acq_parameters
acq_parameters.all_fft_codes = d_all_fft_codes_; acq_parameters.all_fft_codes = d_all_fft_codes_;
// reference for the FPGA FFT-IFFT attenuation factor
acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 14);
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
channel_ = 0;
doppler_step_ = 0;
gnss_synchro_ = nullptr;
// temporary buffers that we can delete // temporary buffers that we can delete
delete[] code; delete[] code;
delete fft_if; delete fft_if;
delete[] fft_codes_padded; delete[] fft_codes_padded;
// vector_length_ = code_length_;
//
// if (bit_transition_flag_)
// {
// vector_length_ *= 2;
// }
//
// code_ = new gr_complex[vector_length_];
//
// if (item_type_.compare("cshort") == 0)
// {
// item_size_ = sizeof(lv_16sc_t);
// }
// else
// {
// item_size_ = sizeof(gr_complex);
// }
// acq_parameters.samples_per_code = code_length_;
// acq_parameters.samples_per_ms = code_length_;
// acq_parameters.it_size = item_size_;
//acq_parameters.sampled_ms = 1;
// acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
// acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
// acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
// acquisition_fpga_ = pcps_make_acquisition(acq_parameters);
// DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
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_ = nullptr;
//printf("L5 ACQ CLASS FINISHED\n");
} }
@ -222,6 +164,8 @@ GpsL5iPcpsAcquisitionFpga::~GpsL5iPcpsAcquisitionFpga()
void GpsL5iPcpsAcquisitionFpga::stop_acquisition() void GpsL5iPcpsAcquisitionFpga::stop_acquisition()
{ {
// this command causes the SW to reset the HW.
acquisition_fpga_->reset_acquisition();
} }
@ -234,25 +178,6 @@ void GpsL5iPcpsAcquisitionFpga::set_channel(unsigned int channel)
void GpsL5iPcpsAcquisitionFpga::set_threshold(float threshold) void GpsL5iPcpsAcquisitionFpga::set_threshold(float threshold)
{ {
// float pfa = configuration_->property(role_ + std::to_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_;
// 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; DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold;
acquisition_fpga_->set_threshold(threshold); acquisition_fpga_->set_threshold(threshold);
} }
@ -303,103 +228,33 @@ void GpsL5iPcpsAcquisitionFpga::reset()
acquisition_fpga_->set_active(true); acquisition_fpga_->set_active(true);
} }
void GpsL5iPcpsAcquisitionFpga::set_state(int state) void GpsL5iPcpsAcquisitionFpga::set_state(int state)
{ {
acquisition_fpga_->set_state(state); acquisition_fpga_->set_state(state);
} }
//float GpsL5iPcpsAcquisitionFpga::calculate_threshold(float pfa)
//{
// //Calculate the threshold
// 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.0 / 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 GpsL5iPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) void GpsL5iPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block)
{ {
// if (item_type_.compare("gr_complex") == 0) if (top_block)
// { { /* top_block is not null */
// top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); };
// } // Nothing to connect
// 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 GpsL5iPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) void GpsL5iPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
{ {
// if (item_type_.compare("gr_complex") == 0) if (top_block)
// { { /* top_block is not null */
// top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); };
// } // Nothing to disconnect
// 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 GpsL5iPcpsAcquisitionFpga::get_left_block() gr::basic_block_sptr GpsL5iPcpsAcquisitionFpga::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;
// }
return nullptr; return nullptr;
} }

View File

@ -1,14 +1,15 @@
/*! /*!
* \file GPS_L5i_PCPS_Acquisition.h * \file GPS_L5i_PCPS_Acquisition_fpga.h
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* GPS L5i signals * GPS L5i signals for the FPGA
* \authors <ul> * \authors <ul>
* <li> Javier Arribas, 2017. jarribas(at)cttc.es * <li> Marc Majoral, 2019. mmajoral(at)cttc.es
* <li> Javier Arribas, 2019. jarribas(at)cttc.es
* </ul> * </ul>
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -66,11 +67,11 @@ public:
} }
/*! /*!
* \brief Returns "GPS_L5i_PCPS_Acquisition" * \brief Returns "GPS_L5i_PCPS_Acquisition_Fpga"
*/ */
inline std::string implementation() override inline std::string implementation() override
{ {
return "GPS_L5i_PCPS_Acquisition"; return "GPS_L5i_PCPS_Acquisition_Fpga";
} }
inline size_t item_size() override inline size_t item_size() override
@ -144,24 +145,22 @@ public:
private: private:
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
//pcps_acquisition_sptr acquisition_;
pcps_acquisition_fpga_sptr acquisition_fpga_; pcps_acquisition_fpga_sptr acquisition_fpga_;
gr::blocks::stream_to_vector::sptr stream_to_vector_; gr::blocks::stream_to_vector::sptr stream_to_vector_;
gr::blocks::float_to_complex::sptr float_to_complex_; gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
size_t item_size_; size_t item_size_;
std::string item_type_; std::string item_type_;
unsigned int vector_length_; uint32_t vector_length_;
unsigned int code_length_; uint32_t code_length_;
bool bit_transition_flag_; bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_; bool use_CFAR_algorithm_flag_;
unsigned int channel_; uint32_t channel_;
float threshold_; float threshold_;
unsigned int doppler_max_; uint32_t doppler_max_;
unsigned int doppler_step_; uint32_t doppler_step_;
unsigned int max_dwells_; uint32_t max_dwells_;
int64_t fs_in_; int64_t fs_in_;
//long if_;
bool dump_; bool dump_;
bool blocking_; bool blocking_;
std::string dump_filename_; std::string dump_filename_;

View File

@ -1,21 +1,14 @@
/*! /*!
* \file pcps_acquisition_fpga.cc * \file pcps_acquisition_fpga.cc
* \brief This class implements a Parallel Code Phase Search Acquisition in the FPGA * \brief This class implements a Parallel Code Phase Search Acquisition for the FPGA
*
* Note: The CFAR algorithm is not implemented in the FPGA.
* Note 2: The bit transition flag is not implemented in the FPGA
*
* \authors <ul> * \authors <ul>
* <li> Marc Majoral, 2017. mmajoral(at)cttc.cat * <li> Marc Majoral, 2019. mmajoral(at)cttc.es
* <li> Javier Arribas, 2011. jarribas(at)cttc.es * <li> Javier Arribas, 2019. jarribas(at)cttc.es
* <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
* <li> Marc Molina, 2013. marc.molina.pena@gmail.com
* <li> Cillian O'Driscoll, 2017. cillian(at)ieee.org
* </ul> * </ul>
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -33,7 +26,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
@ -44,7 +37,6 @@
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <utility> #include <utility>
#define AQ_DOWNSAMPLING_DELAY 40 // delay due to the downsampling filter in the acquisition #define AQ_DOWNSAMPLING_DELAY 40 // delay due to the downsampling filter in the acquisition
using google::LogMessage; using google::LogMessage;
@ -59,14 +51,12 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_) : gr::block(
gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)) gr::io_signature::make(0, 0, 0))
{ {
// printf("acq constructor start\n");
this->message_port_register_out(pmt::mp("events")); this->message_port_register_out(pmt::mp("events"));
acq_parameters = std::move(conf_); acq_parameters = std::move(conf_);
d_sample_counter = 0ULL; // SAMPLE COUNTER d_sample_counter = 0ULL; // SAMPLE COUNTER
d_active = false; d_active = false;
d_state = 0; d_state = 0;
//d_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms;
d_fft_size = acq_parameters.samples_per_code; d_fft_size = acq_parameters.samples_per_code;
d_mag = 0; d_mag = 0;
d_input_power = 0.0; d_input_power = 0.0;
@ -77,49 +67,30 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_) : gr::block(
d_channel = 0U; d_channel = 0U;
d_gnss_synchro = nullptr; d_gnss_synchro = nullptr;
//printf("zzzz acq_parameters.code_length = %d\n", acq_parameters.code_length); d_downsampling_factor = acq_parameters.downsampling_factor;
//printf("zzzz acq_parameters.samples_per_ms = %d\n", acq_parameters.samples_per_ms); d_select_queue_Fpga = acq_parameters.select_queue_Fpga;
//printf("zzzz d_fft_size = %d\n", d_fft_size);
// this one works we don't know why d_total_block_exp = acq_parameters.total_block_exp;
// acquisition_fpga = std::make_shared <fpga_acquisition>
// (acq_parameters.device_name, acq_parameters.code_length, acq_parameters.doppler_max, acq_parameters.samples_per_ms,
// acq_parameters.fs_in, acq_parameters.freq, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes);
// this one is the one it should be but it doesn't work acquisition_fpga = std::make_shared<Fpga_Acquisition>(acq_parameters.device_name, acq_parameters.code_length, acq_parameters.doppler_max, d_fft_size,
acquisition_fpga = std::make_shared<fpga_acquisition>(acq_parameters.device_name, acq_parameters.code_length, acq_parameters.doppler_max, d_fft_size, acq_parameters.fs_in, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes, acq_parameters.excludelimit);
acq_parameters.fs_in, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes);
// acquisition_fpga = std::make_shared <fpga_acquisition>
// (acq_parameters.device_name, acq_parameters.samples_per_code, acq_parameters.doppler_max, acq_parameters.samples_per_code,
// acq_parameters.fs_in, acq_parameters.freq, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes);
// debug
//debug_d_max_absolute = 0.0;
//debug_d_input_power_absolute = 0.0;
// printf("acq constructor end\n");
} }
pcps_acquisition_fpga::~pcps_acquisition_fpga() pcps_acquisition_fpga::~pcps_acquisition_fpga()
{ {
// printf("acq destructor start\n");
acquisition_fpga->free(); acquisition_fpga->free();
// printf("acq destructor end\n");
} }
void pcps_acquisition_fpga::set_local_code() void pcps_acquisition_fpga::set_local_code()
{ {
// printf("acq set local code start\n");
acquisition_fpga->set_local_code(d_gnss_synchro->PRN); acquisition_fpga->set_local_code(d_gnss_synchro->PRN);
// printf("acq set local code end\n");
} }
void pcps_acquisition_fpga::init() void pcps_acquisition_fpga::init()
{ {
// printf("acq init start\n");
d_gnss_synchro->Flag_valid_acquisition = false; d_gnss_synchro->Flag_valid_acquisition = false;
d_gnss_synchro->Flag_valid_symbol_output = false; d_gnss_synchro->Flag_valid_symbol_output = false;
d_gnss_synchro->Flag_valid_pseudorange = false; d_gnss_synchro->Flag_valid_pseudorange = false;
@ -129,23 +100,21 @@ void pcps_acquisition_fpga::init()
d_gnss_synchro->Acq_samplestamp_samples = 0; d_gnss_synchro->Acq_samplestamp_samples = 0;
d_mag = 0.0; d_mag = 0.0;
d_input_power = 0.0; d_input_power = 0.0;
d_num_doppler_bins = static_cast<uint32_t>(std::ceil(static_cast<double>(static_cast<int32_t>(acq_parameters.doppler_max) - static_cast<int32_t>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step)));
d_num_doppler_bins = static_cast<uint32_t>(std::ceil(static_cast<double>(static_cast<int32_t>(acq_parameters.doppler_max) - static_cast<int32_t>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step))) + 1;
acquisition_fpga->init(); acquisition_fpga->init();
// printf("acq init end\n");
} }
void pcps_acquisition_fpga::set_state(int32_t state) void pcps_acquisition_fpga::set_state(int32_t state)
{ {
// printf("acq set state start\n");
d_state = state; d_state = state;
if (d_state == 1) if (d_state == 1)
{ {
d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_delay_samples = 0.0;
d_gnss_synchro->Acq_doppler_hz = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0;
d_gnss_synchro->Acq_samplestamp_samples = 0; d_gnss_synchro->Acq_samplestamp_samples = 0;
//d_well_count = 0;
d_mag = 0.0; d_mag = 0.0;
d_input_power = 0.0; d_input_power = 0.0;
d_test_statistics = 0.0; d_test_statistics = 0.0;
@ -158,14 +127,12 @@ void pcps_acquisition_fpga::set_state(int32_t state)
{ {
LOG(ERROR) << "State can only be set to 0 or 1"; LOG(ERROR) << "State can only be set to 0 or 1";
} }
// printf("acq set state end\n");
} }
void pcps_acquisition_fpga::send_positive_acquisition() void pcps_acquisition_fpga::send_positive_acquisition()
{ {
// printf("acq send positive acquisition start\n"); // Declare positive acquisition using a message port
// 6.1- Declare positive acquisition using a message port
//0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
DLOG(INFO) << "positive acquisition" DLOG(INFO) << "positive acquisition"
<< ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
@ -178,15 +145,12 @@ void pcps_acquisition_fpga::send_positive_acquisition()
<< ", input signal power " << d_input_power; << ", input signal power " << d_input_power;
this->message_port_pub(pmt::mp("events"), pmt::from_long(1)); this->message_port_pub(pmt::mp("events"), pmt::from_long(1));
// printf("acq send positive acquisition end\n");
} }
void pcps_acquisition_fpga::send_negative_acquisition() void pcps_acquisition_fpga::send_negative_acquisition()
{ {
// printf("acq send negative acquisition start\n"); // Declare negative acquisition using a message port
// 6.2- Declare negative acquisition using a message port
//0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
DLOG(INFO) << "negative acquisition" DLOG(INFO) << "negative acquisition"
<< ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
<< ", sample_stamp " << d_sample_counter << ", sample_stamp " << d_sample_counter
@ -198,23 +162,24 @@ void pcps_acquisition_fpga::send_negative_acquisition()
<< ", input signal power " << d_input_power; << ", input signal power " << d_input_power;
this->message_port_pub(pmt::mp("events"), pmt::from_long(2)); this->message_port_pub(pmt::mp("events"), pmt::from_long(2));
// printf("acq send negative acquisition end\n");
} }
void pcps_acquisition_fpga::set_active(bool active) void pcps_acquisition_fpga::set_active(bool active)
{ {
// printf("acq set active start\n");
d_active = active; d_active = active;
// initialize acquisition algorithm // initialize acquisition algorithm
uint32_t indext = 0U; uint32_t indext = 0U;
float magt = 0.0; float firstpeak = 0.0;
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size); float secondpeak = 0.0;
uint32_t total_block_exp;
d_input_power = 0.0; d_input_power = 0.0;
d_mag = 0.0; d_mag = 0.0;
int32_t doppler;
DLOG(INFO) << "Channel: " << d_channel DLOG(INFO) << "Channel: " << d_channel
<< " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN << " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
<< " ,sample stamp: " << d_sample_counter << ", threshold: " << " ,sample stamp: " << d_sample_counter << ", threshold: "
@ -224,112 +189,57 @@ void pcps_acquisition_fpga::set_active(bool active)
<< ", use_CFAR_algorithm_flag: false"; << ", use_CFAR_algorithm_flag: false";
uint64_t initial_sample; uint64_t initial_sample;
float input_power_all = 0.0;
float input_power_computed = 0.0;
float temp_d_input_power; acquisition_fpga->configure_acquisition();
// loop through acquisition
/*
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
{
// doppler search steps
int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
//acquisition_fpga->set_phase_step(doppler_index);
acquisition_fpga->set_doppler_sweep_debug(1, doppler_index);
acquisition_fpga->run_acquisition(); // runs acquisition and waits until it is finished
acquisition_fpga->read_acquisition_results(&indext, &magt,
&initial_sample, &d_input_power, &d_doppler_index);
d_sample_counter = initial_sample;
if (d_mag < magt)
{
d_mag = magt;
temp_d_input_power = d_input_power;
input_power_all = d_input_power / (d_fft_size - 1);
input_power_computed = (d_input_power - d_mag) / (d_fft_size - 1);
d_input_power = (d_input_power - d_mag) / (d_fft_size - 1);
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code);
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
d_test_statistics = (d_mag / d_input_power); // correction_factor;
}
// In the case of the FPGA the option of dumping the results of the acquisition to a file is not available
// because the IFFT vector is not available
}
*/
// debug
//acquisition_fpga->block_samples();
// run loop in hw
//printf("LAUNCH ACQ\n");
acquisition_fpga->set_doppler_sweep(d_num_doppler_bins); acquisition_fpga->set_doppler_sweep(d_num_doppler_bins);
acquisition_fpga->write_local_code();
acquisition_fpga->set_block_exp(d_total_block_exp);
acquisition_fpga->run_acquisition(); acquisition_fpga->run_acquisition();
acquisition_fpga->read_acquisition_results(&indext, &magt, acquisition_fpga->read_acquisition_results(&indext, &firstpeak, &secondpeak, &initial_sample, &d_input_power, &d_doppler_index, &total_block_exp);
&initial_sample, &d_input_power, &d_doppler_index);
//printf("READ ACQ RESULTS\n");
// debug if (total_block_exp > d_total_block_exp)
//acquisition_fpga->unblock_samples(); {
// if the attenuation factor of the FPGA FFT-IFFT is smaller than the reference attenuation factor then we need to update the reference attenuation factor
std::cout << "changing blk exp..... d_total_block_exp = " << d_total_block_exp << " total_block_exp = " << total_block_exp << " chan = " << d_channel << std::endl;
d_total_block_exp = total_block_exp;
}
d_mag = magt; doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * (d_doppler_index - 1);
if (secondpeak > 0)
{
d_test_statistics = firstpeak / secondpeak;
}
else
{
d_test_statistics = 0.0;
}
// debug
debug_d_max_absolute = magt;
debug_d_input_power_absolute = d_input_power;
debug_indext = indext;
debug_doppler_index = d_doppler_index;
// temp_d_input_power = d_input_power;
d_input_power = (d_input_power - d_mag) / (d_fft_size - 1);
int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * d_doppler_index;
//d_gnss_synchro->Acq_delay_samples = static_cast<double>(2*(indext % (2*acq_parameters.samples_per_code)));
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code);
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_sample_counter = initial_sample; d_sample_counter = initial_sample;
//d_gnss_synchro->Acq_samplestamp_samples = 2*d_sample_counter - 81; // delay due to the downsampling filter in the acquisition
//d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter - 40; // delay due to the downsampling filter in the acquisition if (d_select_queue_Fpga == 0)
{
if (d_downsampling_factor > 1)
{
d_gnss_synchro->Acq_delay_samples = static_cast<double>(d_downsampling_factor * (indext));
d_gnss_synchro->Acq_samplestamp_samples = d_downsampling_factor * d_sample_counter - 44; //33; //41; //+ 81*0.5; // delay due to the downsampling filter in the acquisition
}
else
{
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext);
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; // delay due to the downsampling filter in the acquisition d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; // delay due to the downsampling filter in the acquisition
d_test_statistics = (d_mag / d_input_power); //* correction_factor; }
}
// debug else
// if (d_gnss_synchro->Acq_delay_samples > acq_parameters.code_length) {
// { d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext);
// printf("d_gnss_synchro->Acq_samplestamp_samples = %d\n", d_gnss_synchro->Acq_samplestamp_samples); d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; // delay due to the downsampling filter in the acquisition
// printf("d_gnss_synchro->Acq_delay_samples = %f\n", d_gnss_synchro->Acq_delay_samples); }
// }
// if (temp_d_input_power > debug_d_input_power_absolute)
// {
// debug_d_max_absolute = d_mag;
// debug_d_input_power_absolute = temp_d_input_power;
// }
// printf ("max debug_d_max_absolute = %f\n", debug_d_max_absolute);
// printf ("debug_d_input_power_absolute = %f\n", debug_d_input_power_absolute);
// printf("&&&&& d_test_statistics = %f\n", d_test_statistics);
// printf("&&&&& debug_d_max_absolute =%f\n",debug_d_max_absolute);
// printf("&&&&& debug_d_input_power_absolute =%f\n",debug_d_input_power_absolute);
// printf("&&&&& debug_indext = %d\n",debug_indext);
// printf("&&&&& debug_doppler_index = %d\n",debug_doppler_index);
if (d_test_statistics > d_threshold) if (d_test_statistics > d_threshold)
{ {
d_active = false; d_active = false;
// printf("##### d_test_statistics = %f\n", d_test_statistics);
// printf("##### debug_d_max_absolute =%f\n",debug_d_max_absolute);
// printf("##### debug_d_input_power_absolute =%f\n",debug_d_input_power_absolute);
// printf("##### initial_sample = %llu\n",initial_sample);
// printf("##### debug_doppler_index = %d\n",debug_doppler_index);
send_positive_acquisition(); send_positive_acquisition();
d_state = 0; // Positive acquisition d_state = 0; // Positive acquisition
} }
@ -339,8 +249,6 @@ void pcps_acquisition_fpga::set_active(bool active)
d_active = false; d_active = false;
send_negative_acquisition(); send_negative_acquisition();
} }
// printf("acq set active end\n");
} }
@ -351,3 +259,16 @@ int pcps_acquisition_fpga::general_work(int noutput_items __attribute__((unused)
// the general work is not used with the acquisition that uses the FPGA // the general work is not used with the acquisition that uses the FPGA
return noutput_items; return noutput_items;
} }
void pcps_acquisition_fpga::reset_acquisition(void)
{
// this function triggers a HW reset of the FPGA PL.
acquisition_fpga->reset_acquisition();
}
void pcps_acquisition_fpga::read_fpga_total_scale_factor(uint32_t* total_scale_factor, uint32_t* fw_scale_factor)
{
acquisition_fpga->read_fpga_total_scale_factor(total_scale_factor, fw_scale_factor);
}

View File

@ -1,36 +1,20 @@
/*! /*!
* \file pcps_acquisition_fpga.h * \file pcps_acquisition_fpga.h
* \brief This class implements a Parallel Code Phase Search Acquisition in the FPGA. * \brief This class implements a Parallel Code Phase Search Acquisition for the FPGA
* *
* Note: The CFAR algorithm is not implemented in the FPGA.
* Note 2: The bit transition flag is not implemented in the FPGA
*
* Acquisition strategy (Kay Borre book + CFAR threshold).
* <ol>
* <li> Compute the input signal power estimation
* <li> Doppler serial search loop
* <li> Perform the FFT-based circular convolution (parallel time search)
* <li> Record the maximum peak and the associated synchronization parameters
* <li> Compute the test statistics and compare to the threshold
* <li> Declare positive or negative acquisition using a message queue
* </ol>
* *
* Kay Borre book: K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, * Kay Borre book: K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
* "A Software-Defined GPS and Galileo Receiver. A Single-Frequency * "A Software-Defined GPS and Galileo Receiver. A Single-Frequency
* Approach", Birkhauser, 2007. pp 81-84 * Approach", Birkhauser, 2007. pp 81-84
* *
* \authors <ul> * \authors <ul>
* <li> Marc Majoral, 2017. mmajoral(at)cttc.cat * <li> Marc Majoral, 2019. mmajoral(at)cttc.es
* <li> Javier Arribas, 2011. jarribas(at)cttc.es * <li> Javier Arribas, 2019. jarribas(at)cttc.es
* <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
* <li> Marc Molina, 2013. marc.molina.pena@gmail.com
* <li> Cillian O'Driscoll, 2017. cillian(at)ieee.org
* <li> Antonio Ramos, 2017. antonio.ramos@cttc.es
* </ul> * </ul>
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -73,12 +57,14 @@ typedef struct
uint32_t select_queue_Fpga; uint32_t select_queue_Fpga;
std::string device_name; std::string device_name;
lv_16sc_t* all_fft_codes; // memory that contains all the code ffts lv_16sc_t* all_fft_codes; // memory that contains all the code ffts
float downsampling_factor;
uint32_t total_block_exp;
uint32_t excludelimit;
} pcpsconf_fpga_t; } pcpsconf_fpga_t;
class pcps_acquisition_fpga; class pcps_acquisition_fpga;
typedef boost::shared_ptr<pcps_acquisition_fpga> pcps_acquisition_fpga_sptr; using pcps_acquisition_fpga_sptr = boost::shared_ptr<pcps_acquisition_fpga>;
pcps_acquisition_fpga_sptr pcps_acquisition_fpga_sptr
pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_); pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_);
@ -102,6 +88,8 @@ private:
void send_positive_acquisition(); void send_positive_acquisition();
float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
pcpsconf_fpga_t acq_parameters; pcpsconf_fpga_t acq_parameters;
bool d_active; bool d_active;
float d_threshold; float d_threshold;
@ -116,13 +104,12 @@ private:
uint32_t d_num_doppler_bins; uint32_t d_num_doppler_bins;
uint64_t d_sample_counter; uint64_t d_sample_counter;
Gnss_Synchro* d_gnss_synchro; Gnss_Synchro* d_gnss_synchro;
std::shared_ptr<fpga_acquisition> acquisition_fpga; std::shared_ptr<Fpga_Acquisition> acquisition_fpga;
// debug float d_downsampling_factor;
float debug_d_max_absolute; uint32_t d_select_queue_Fpga;
float debug_d_input_power_absolute;
int32_t debug_indext; uint32_t d_total_block_exp;
int32_t debug_doppler_index;
public: public:
~pcps_acquisition_fpga(); ~pcps_acquisition_fpga();
@ -134,9 +121,7 @@ public:
*/ */
inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
{ {
// printf("acq set gnss synchro start\n");
d_gnss_synchro = p_gnss_synchro; d_gnss_synchro = p_gnss_synchro;
// printf("acq set gnss synchro end\n");
} }
/*! /*!
@ -144,9 +129,7 @@ public:
*/ */
inline uint32_t mag() const inline uint32_t mag() const
{ {
// printf("acq dmag start\n");
return d_mag; return d_mag;
// printf("acq dmag end\n");
} }
/*! /*!
@ -190,9 +173,7 @@ public:
*/ */
inline void set_threshold(float threshold) inline void set_threshold(float threshold)
{ {
// printf("acq set threshold start\n");
d_threshold = threshold; d_threshold = threshold;
// printf("acq set threshold end\n");
} }
/*! /*!
@ -201,10 +182,8 @@ public:
*/ */
inline void set_doppler_max(uint32_t doppler_max) inline void set_doppler_max(uint32_t doppler_max)
{ {
// printf("acq set doppler max start\n");
acq_parameters.doppler_max = doppler_max; acq_parameters.doppler_max = doppler_max;
acquisition_fpga->set_doppler_max(doppler_max); acquisition_fpga->set_doppler_max(doppler_max);
// printf("acq set doppler max end\n");
} }
/*! /*!
@ -213,10 +192,8 @@ public:
*/ */
inline void set_doppler_step(uint32_t doppler_step) inline void set_doppler_step(uint32_t doppler_step)
{ {
// printf("acq set doppler step start\n");
d_doppler_step = doppler_step; d_doppler_step = doppler_step;
acquisition_fpga->set_doppler_step(doppler_step); acquisition_fpga->set_doppler_step(doppler_step);
// printf("acq set doppler step end\n");
} }
/*! /*!
@ -225,6 +202,16 @@ public:
int general_work(int noutput_items, gr_vector_int& ninput_items, int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items); gr_vector_void_star& output_items);
/*!
* \brief This funciton triggers a HW reset of the FPGA PL.
*/
void reset_acquisition(void);
/*!
* \brief This funciton is only used for the unit tests
*/
void read_fpga_total_scale_factor(uint32_t* total_scale_factor, uint32_t* fw_scale_factor);
}; };
#endif /* GNSS_SDR_PCPS_ACQUISITION_FPGA_H_*/ #endif /* GNSS_SDR_PCPS_ACQUISITION_FPGA_H_*/

View File

@ -2,7 +2,7 @@
* \file fpga_acquisition.cc * \file fpga_acquisition.cc
* \brief High optimized FPGA vector correlator class * \brief High optimized FPGA vector correlator class
* \authors <ul> * \authors <ul>
* <li> Marc Majoral, 2018. mmajoral(at)cttc.cat * <li> Marc Majoral, 2019. mmajoral(at)cttc.cat
* </ul> * </ul>
* *
* Class that controls and executes a high optimized acquisition HW * Class that controls and executes a high optimized acquisition HW
@ -43,6 +43,7 @@
#include <utility> #include <utility>
// FPGA register parameters
#define PAGE_SIZE 0x10000 // default page size for the multicorrelator memory map #define PAGE_SIZE 0x10000 // default page size for the multicorrelator memory map
#define MAX_PHASE_STEP_RAD 0.999999999534339 // 1 - pow(2,-31); #define MAX_PHASE_STEP_RAD 0.999999999534339 // 1 - pow(2,-31);
#define RESET_ACQUISITION 2 // command to reset the multicorrelator #define RESET_ACQUISITION 2 // command to reset the multicorrelator
@ -56,57 +57,48 @@
#define SELECT_MSB 0XFF00 // value to select the most significant byte #define SELECT_MSB 0XFF00 // value to select the most significant byte
#define SELECT_16_BITS 0xFFFF // value to select 16 bits #define SELECT_16_BITS 0xFFFF // value to select 16 bits
#define SHL_8_BITS 256 // value used to shift a value 8 bits to the left #define SHL_8_BITS 256 // value used to shift a value 8 bits to the left
#define SELECT_LSBits 0x000003FF // Select the 10 LSbits out of a 20-bit word
// 12-bits #define SELECT_MSBbits 0x000FFC00 // Select the 10 MSbits out of a 20-bit word
//#define SELECT_LSBits 0x0FFF #define SELECT_ALL_CODE_BITS 0x000FFFFF // Select a 20 bit word
//#define SELECT_MSBbits 0x00FFF000 #define SHL_CODE_BITS 1024 // shift left by 10 bits
//#define SELECT_24_BITS 0x00FFFFFF
//#define SHL_12_BITS 4096
// 16-bits
#define SELECT_LSBits 0x0FFFF
#define SELECT_MSBbits 0xFFFF0000
#define SELECT_32_BITS 0xFFFFFFFF
#define SHL_16_BITS 65536
bool fpga_acquisition::init() bool Fpga_Acquisition::init()
{ {
// configure the acquisition with the main initialization values
fpga_acquisition::configure_acquisition();
return true; return true;
} }
bool fpga_acquisition::set_local_code(uint32_t PRN) bool Fpga_Acquisition::set_local_code(uint32_t PRN)
{ {
// select the code with the chosen PRN // select the code with the chosen PRN
fpga_acquisition::fpga_configure_acquisition_local_code( d_PRN = PRN;
&d_all_fft_codes[d_nsamples_total * (PRN - 1)]);
//fpga_acquisition::fpga_configure_acquisition_local_code(
// &d_all_fft_codes[0]);
return true; return true;
} }
fpga_acquisition::fpga_acquisition(std::string device_name, void Fpga_Acquisition::write_local_code()
{
Fpga_Acquisition::fpga_configure_acquisition_local_code(
&d_all_fft_codes[d_nsamples_total * (d_PRN - 1)]);
}
Fpga_Acquisition::Fpga_Acquisition(std::string device_name,
uint32_t nsamples, uint32_t nsamples,
uint32_t doppler_max, uint32_t doppler_max,
uint32_t nsamples_total, int64_t fs_in, uint32_t nsamples_total, int64_t fs_in,
uint32_t sampled_ms, uint32_t select_queue, uint32_t sampled_ms, uint32_t select_queue,
lv_16sc_t *all_fft_codes) lv_16sc_t *all_fft_codes,
uint32_t excludelimit)
{ {
//printf("AAA- sampled_ms = %d\n ", sampled_ms); uint32_t vector_length = nsamples_total;
uint32_t vector_length = nsamples_total; // * sampled_ms;
//printf("AAA- vector_length = %d\n ", vector_length);
// initial values // initial values
d_device_name = std::move(device_name); d_device_name = std::move(device_name);
//d_freq = freq;
d_fs_in = fs_in; d_fs_in = fs_in;
d_vector_length = vector_length; d_vector_length = vector_length;
d_excludelimit = excludelimit;
d_nsamples = nsamples; // number of samples not including padding d_nsamples = nsamples; // number of samples not including padding
d_select_queue = select_queue; d_select_queue = select_queue;
d_nsamples_total = nsamples_total; d_nsamples_total = nsamples_total;
@ -116,6 +108,18 @@ fpga_acquisition::fpga_acquisition(std::string device_name,
d_map_base = nullptr; // driver memory map d_map_base = nullptr; // driver memory map
d_all_fft_codes = all_fft_codes; d_all_fft_codes = all_fft_codes;
Fpga_Acquisition::reset_acquisition();
Fpga_Acquisition::open_device();
Fpga_Acquisition::fpga_acquisition_test_register();
Fpga_Acquisition::close_device();
d_PRN = 0;
DLOG(INFO) << "Acquisition FPGA class created";
}
void Fpga_Acquisition::open_device()
{
// open communication with HW accelerator // open communication with HW accelerator
if ((d_fd = open(d_device_name.c_str(), O_RDWR | O_SYNC)) == -1) if ((d_fd = open(d_device_name.c_str(), O_RDWR | O_SYNC)) == -1)
{ {
@ -130,11 +134,29 @@ fpga_acquisition::fpga_acquisition(std::string device_name,
LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory"; LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory";
std::cout << "Acq: cannot map deviceio" << d_device_name << std::endl; std::cout << "Acq: cannot map deviceio" << d_device_name << std::endl;
} }
}
Fpga_Acquisition::~Fpga_Acquisition() = default;
bool Fpga_Acquisition::free()
{
return true;
}
void Fpga_Acquisition::fpga_acquisition_test_register()
{
// sanity check : check test register // sanity check : check test register
uint32_t writeval = TEST_REG_SANITY_CHECK; uint32_t writeval = TEST_REG_SANITY_CHECK;
uint32_t readval; uint32_t readval;
readval = fpga_acquisition::fpga_acquisition_test_register(writeval);
// write value to test register
d_map_base[15] = writeval;
// read value from test register
readval = d_map_base[15];
if (writeval != readval) if (writeval != readval)
{ {
LOG(WARNING) << "Acquisition test register sanity check failed"; LOG(WARNING) << "Acquisition test register sanity check failed";
@ -142,208 +164,115 @@ fpga_acquisition::fpga_acquisition(std::string device_name,
else else
{ {
LOG(INFO) << "Acquisition test register sanity check success!"; LOG(INFO) << "Acquisition test register sanity check success!";
//std::cout << "Acquisition test register sanity check success!" << std::endl;
} }
fpga_acquisition::reset_acquisition();
DLOG(INFO) << "Acquisition FPGA class created";
} }
fpga_acquisition::~fpga_acquisition() void Fpga_Acquisition::fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[])
{
close_device();
}
bool fpga_acquisition::free()
{
return true;
}
uint32_t fpga_acquisition::fpga_acquisition_test_register(uint32_t writeval)
{
uint32_t readval;
// write value to test register
d_map_base[15] = writeval;
// read value from test register
readval = d_map_base[15];
// return read value
return readval;
}
void fpga_acquisition::fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[])
{ {
uint32_t local_code; uint32_t local_code;
uint32_t k, tmp, tmp2; uint32_t k, tmp, tmp2;
uint32_t fft_data; uint32_t fft_data;
// clear memory address counter
//d_map_base[6] = LOCAL_CODE_CLEAR_MEM;
d_map_base[9] = LOCAL_CODE_CLEAR_MEM; d_map_base[9] = LOCAL_CODE_CLEAR_MEM;
// write local code // write local code
for (k = 0; k < d_vector_length; k++) for (k = 0; k < d_vector_length; k++)
{ {
tmp = fft_local_code[k].real(); tmp = fft_local_code[k].real();
tmp2 = fft_local_code[k].imag(); tmp2 = fft_local_code[k].imag();
//tmp = k;
//tmp2 = k;
//local_code = (tmp & SELECT_LSB) | ((tmp2 * SHL_8_BITS) & SELECT_MSB); // put together the real part and the imaginary part local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part
//fft_data = MEM_LOCAL_CODE_WR_ENABLE | (local_code & SELECT_16_BITS); fft_data = local_code & SELECT_ALL_CODE_BITS;
//local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_12_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part
local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_16_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part
//fft_data = MEM_LOCAL_CODE_WR_ENABLE | (local_code & SELECT_24_BITS);
fft_data = local_code & SELECT_32_BITS;
d_map_base[6] = fft_data; d_map_base[6] = fft_data;
//printf("debug local code %d real = %d imag = %d local_code = %d fft_data = %d\n", k, tmp, tmp2, local_code, fft_data);
//printf("debug local code %d real = 0x%08X imag = 0x%08X local_code = 0x%08X fft_data = 0x%08X\n", k, tmp, tmp2, local_code, fft_data);
} }
//printf("d_vector_length = %d\n", d_vector_length);
//while(1);
} }
void fpga_acquisition::run_acquisition(void) void Fpga_Acquisition::run_acquisition(void)
{ {
// enable interrupts // enable interrupts
int32_t reenable = 1; int32_t reenable = 1;
int32_t disable_int = 0;
write(d_fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t)); write(d_fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t));
// launch the acquisition process
//printf("launchin acquisition ...\n");
d_map_base[8] = LAUNCH_ACQUISITION; // writing a 1 to reg 8 launches the acquisition process
// launch the acquisition process
d_map_base[8] = LAUNCH_ACQUISITION; // writing a 1 to reg 8 launches the acquisition process
int32_t irq_count; int32_t irq_count;
ssize_t nb; ssize_t nb;
// wait for interrupt // wait for interrupt
nb = read(d_fd, &irq_count, sizeof(irq_count)); nb = read(d_fd, &irq_count, sizeof(irq_count));
//printf("interrupt received\n");
if (nb != sizeof(irq_count)) if (nb != sizeof(irq_count))
{ {
printf("acquisition module Read failed to retrieve 4 bytes!\n"); std::cout << "acquisition module Read failed to retrieve 4 bytes!" << std::endl;
printf("acquisition module Interrupt number %d\n", irq_count); std::cout << "acquisition module Interrupt number " << irq_count << std::endl;
} }
write(d_fd, reinterpret_cast<void *>(&disable_int), sizeof(int32_t));
} }
void fpga_acquisition::set_doppler_sweep(uint32_t num_sweeps) void Fpga_Acquisition::set_block_exp(uint32_t total_block_exp)
{
d_map_base[11] = total_block_exp;
}
void Fpga_Acquisition::set_doppler_sweep(uint32_t num_sweeps)
{ {
float phase_step_rad_real; float phase_step_rad_real;
float phase_step_rad_int_temp; float phase_step_rad_int_temp;
int32_t phase_step_rad_int; int32_t phase_step_rad_int;
//int32_t doppler = static_cast<int32_t>(-d_doppler_max) + d_doppler_step * doppler_index;
auto doppler = static_cast<int32_t>(-d_doppler_max); auto doppler = static_cast<int32_t>(-d_doppler_max);
//float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in);
float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in); float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in);
// The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing
// The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi)
// The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x) // The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x)
// while the gnss-sdr software (volk_gnsssdr_s32f_sincos_32fc) generates cos(x) + j*sin(x)
phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2);
// avoid saturation of the fixed point representation in the fpga // avoid saturation of the fixed point representation in the fpga
// (only the positive value can saturate due to the 2's complement representation) // (only the positive value can saturate due to the 2's complement representation)
//printf("AAA phase_step_rad_real for initial doppler = %f\n", phase_step_rad_real);
if (phase_step_rad_real >= 1.0) if (phase_step_rad_real >= 1.0)
{ {
phase_step_rad_real = MAX_PHASE_STEP_RAD; phase_step_rad_real = MAX_PHASE_STEP_RAD;
} }
//printf("AAA phase_step_rad_real for initial doppler after checking = %f\n", phase_step_rad_real);
phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
//printf("AAA writing phase_step_rad_int for initial doppler = %d to d map base 3\n", phase_step_rad_int);
d_map_base[3] = phase_step_rad_int; d_map_base[3] = phase_step_rad_int;
// repeat the calculation with the doppler step // repeat the calculation with the doppler step
doppler = static_cast<int32_t>(d_doppler_step); doppler = static_cast<int32_t>(d_doppler_step);
phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in); phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in);
phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2);
//printf("AAA phase_step_rad_real for doppler step = %f\n", phase_step_rad_real);
if (phase_step_rad_real >= 1.0) if (phase_step_rad_real >= 1.0)
{ {
phase_step_rad_real = MAX_PHASE_STEP_RAD; phase_step_rad_real = MAX_PHASE_STEP_RAD;
} }
//printf("AAA phase_step_rad_real for doppler step after checking = %f\n", phase_step_rad_real);
phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
//printf("AAA writing phase_step_rad_int for doppler step = %d to d map base 4\n", phase_step_rad_int);
d_map_base[4] = phase_step_rad_int; d_map_base[4] = phase_step_rad_int;
//printf("AAA writing num sweeps to d map base 5 = %d\n", num_sweeps);
d_map_base[5] = num_sweeps;
}
void fpga_acquisition::set_doppler_sweep_debug(uint32_t num_sweeps, uint32_t doppler_index)
{
float phase_step_rad_real;
float phase_step_rad_int_temp;
int32_t phase_step_rad_int;
int32_t doppler = -static_cast<int32_t>(d_doppler_max) + d_doppler_step * doppler_index;
//int32_t doppler = static_cast<int32_t>(-d_doppler_max);
//float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in);
float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in);
// The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing
// The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi)
// The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x)
// while the gnss-sdr software (volk_gnsssdr_s32f_sincos_32fc) generates cos(x) + j*sin(x)
phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2);
// avoid saturation of the fixed point representation in the fpga
// (only the positive value can saturate due to the 2's complement representation)
//printf("AAAh phase_step_rad_real for initial doppler = %f\n", phase_step_rad_real);
if (phase_step_rad_real >= 1.0)
{
phase_step_rad_real = MAX_PHASE_STEP_RAD;
}
//printf("AAAh phase_step_rad_real for initial doppler after checking = %f\n", phase_step_rad_real);
phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
//printf("AAAh writing phase_step_rad_int for initial doppler = %d to d map base 3\n", phase_step_rad_int);
d_map_base[3] = phase_step_rad_int;
// repeat the calculation with the doppler step
doppler = static_cast<int32_t>(d_doppler_step);
phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in);
phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2);
//printf("AAAh phase_step_rad_real for doppler step = %f\n", phase_step_rad_real);
if (phase_step_rad_real >= 1.0)
{
phase_step_rad_real = MAX_PHASE_STEP_RAD;
}
//printf("AAAh phase_step_rad_real for doppler step after checking = %f\n", phase_step_rad_real);
phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
//printf("AAAh writing phase_step_rad_int for doppler step = %d to d map base 4\n", phase_step_rad_int);
d_map_base[4] = phase_step_rad_int;
//printf("AAAh writing num sweeps to d map base 5 = %d\n", num_sweeps);
d_map_base[5] = num_sweeps; d_map_base[5] = num_sweeps;
} }
void fpga_acquisition::configure_acquisition() void Fpga_Acquisition::configure_acquisition()
{ {
//printf("AAA d_select_queue = %d\n", d_select_queue); Fpga_Acquisition::open_device();
d_map_base[0] = d_select_queue; d_map_base[0] = d_select_queue;
//printf("AAA writing d_vector_length = %d to d map base 1\n ", d_vector_length);
d_map_base[1] = d_vector_length; d_map_base[1] = d_vector_length;
//printf("AAA writing d_nsamples = %d to d map base 2\n ", d_nsamples);
d_map_base[2] = d_nsamples; d_map_base[2] = d_nsamples;
//printf("AAA writing LOG2 d_vector_length = %d to d map base 7\n ", (int)log2((float)d_vector_length));
d_map_base[7] = static_cast<int32_t>(log2(static_cast<float>(d_vector_length))); // log2 FFTlength d_map_base[7] = static_cast<int32_t>(log2(static_cast<float>(d_vector_length))); // log2 FFTlength
//printf("acquisition debug vector length = %d\n", d_vector_length); d_map_base[12] = d_excludelimit;
//printf("acquisition debug vector length = %d\n", (int)log2((float)d_vector_length));
} }
void fpga_acquisition::set_phase_step(uint32_t doppler_index) void Fpga_Acquisition::set_phase_step(uint32_t doppler_index)
{ {
float phase_step_rad_real; float phase_step_rad_real;
float phase_step_rad_int_temp; float phase_step_rad_int_temp;
int32_t phase_step_rad_int; int32_t phase_step_rad_int;
int32_t doppler = -static_cast<int32_t>(d_doppler_max) + d_doppler_step * doppler_index; int32_t doppler = -static_cast<int32_t>(d_doppler_max) + d_doppler_step * doppler_index;
//float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in);
float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in); float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in);
// The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing
// The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi)
@ -352,73 +281,101 @@ void fpga_acquisition::set_phase_step(uint32_t doppler_index)
phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2);
// avoid saturation of the fixed point representation in the fpga // avoid saturation of the fixed point representation in the fpga
// (only the positive value can saturate due to the 2's complement representation) // (only the positive value can saturate due to the 2's complement representation)
//printf("AAA+ phase_step_rad_real = %f\n", phase_step_rad_real);
if (phase_step_rad_real >= 1.0) if (phase_step_rad_real >= 1.0)
{ {
phase_step_rad_real = MAX_PHASE_STEP_RAD; phase_step_rad_real = MAX_PHASE_STEP_RAD;
} }
//printf("AAA+ phase_step_rad_real after checking = %f\n", phase_step_rad_real);
phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
//printf("writing phase_step_rad_int = %d to d_map_base 3\n", phase_step_rad_int);
d_map_base[3] = phase_step_rad_int; d_map_base[3] = phase_step_rad_int;
} }
void fpga_acquisition::read_acquisition_results(uint32_t *max_index, void Fpga_Acquisition::read_acquisition_results(uint32_t *max_index,
float *max_magnitude, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index) float *firstpeak, float *secondpeak, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index, uint32_t *total_blk_exp)
{ {
uint64_t initial_sample_tmp = 0; uint64_t initial_sample_tmp = 0;
uint32_t readval = 0; uint32_t readval = 0;
uint64_t readval_long = 0; uint64_t readval_long = 0;
uint64_t readval_long_shifted = 0; uint64_t readval_long_shifted = 0;
readval = d_map_base[1]; readval = d_map_base[1];
initial_sample_tmp = readval; initial_sample_tmp = readval;
readval_long = d_map_base[2]; readval_long = d_map_base[2];
readval_long_shifted = readval_long << 32; // 2^32 readval_long_shifted = readval_long << 32; // 2^32
initial_sample_tmp = initial_sample_tmp + readval_long_shifted; // 2^32 initial_sample_tmp = initial_sample_tmp + readval_long_shifted; // 2^32
//printf("----------------------------------------------------------------> acq initial sample TOTAL = %llu\n", initial_sample_tmp);
*initial_sample = initial_sample_tmp; *initial_sample = initial_sample_tmp;
readval = d_map_base[6];
*max_magnitude = static_cast<float>(readval);
//printf("read max_magnitude dmap 2 = %d\n", readval);
readval = d_map_base[4];
*power_sum = static_cast<float>(readval);
//printf("read power sum dmap 4 = %d\n", readval);
readval = d_map_base[5]; // read doppler index
*doppler_index = readval;
//printf("read doppler_index dmap 5 = %d\n", readval);
readval = d_map_base[3]; readval = d_map_base[3];
*firstpeak = static_cast<float>(readval);
readval = d_map_base[4];
*secondpeak = static_cast<float>(readval);
readval = d_map_base[5];
*max_index = readval; *max_index = readval;
//printf("read max index dmap 3 = %d\n", readval);
*power_sum = 0;
readval = d_map_base[8];
*total_blk_exp = readval;
readval = d_map_base[7]; // read doppler index -- this read releases the interrupt line
*doppler_index = readval;
readval = d_map_base[15]; // read dummy
Fpga_Acquisition::close_device();
} }
void fpga_acquisition::block_samples() void Fpga_Acquisition::block_samples()
{ {
d_map_base[14] = 1; // block the samples d_map_base[14] = 1; // block the samples
} }
void fpga_acquisition::unblock_samples() void Fpga_Acquisition::unblock_samples()
{ {
d_map_base[14] = 0; // unblock the samples d_map_base[14] = 0; // unblock the samples
} }
void fpga_acquisition::close_device() void Fpga_Acquisition::close_device()
{ {
auto *aux = const_cast<uint32_t *>(d_map_base); auto *aux = const_cast<uint32_t *>(d_map_base);
if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1) if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1)
{ {
printf("Failed to unmap memory uio\n"); std::cout << "Failed to unmap memory uio" << std::endl;
} }
close(d_fd); close(d_fd);
} }
void fpga_acquisition::reset_acquisition(void) void Fpga_Acquisition::reset_acquisition(void)
{ {
Fpga_Acquisition::open_device();
d_map_base[8] = RESET_ACQUISITION; // writing a 2 to d_map_base[8] resets the multicorrelator d_map_base[8] = RESET_ACQUISITION; // writing a 2 to d_map_base[8] resets the multicorrelator
Fpga_Acquisition::close_device();
}
// this function is only used for the unit tests
void Fpga_Acquisition::read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor)
{
uint32_t readval = 0;
readval = d_map_base[8];
*total_scale_factor = readval;
//readval = d_map_base[8];
*fw_scale_factor = 0;
}
void Fpga_Acquisition::read_result_valid(uint32_t *result_valid)
{
uint32_t readval = 0;
readval = d_map_base[0];
*result_valid = readval;
} }

View File

@ -2,7 +2,7 @@
* \file fpga_acquisition.h * \file fpga_acquisition.h
* \brief High optimized FPGA vector correlator class * \brief High optimized FPGA vector correlator class
* \authors <ul> * \authors <ul>
* <li> Marc Majoral, 2018. mmajoral(at)cttc.cat * <li> Marc Majoral, 2019. mmajoral(at)cttc.cat
* </ul> * </ul>
* *
* Class that controls and executes a high optimized acquisition HW * Class that controls and executes a high optimized acquisition HW
@ -10,7 +10,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -43,28 +43,28 @@
/*! /*!
* \brief Class that implements carrier wipe-off and correlators. * \brief Class that implements carrier wipe-off and correlators.
*/ */
class fpga_acquisition class Fpga_Acquisition
{ {
public: public:
fpga_acquisition(std::string device_name, Fpga_Acquisition(std::string device_name,
uint32_t nsamples, uint32_t nsamples,
uint32_t doppler_max, uint32_t doppler_max,
uint32_t nsamples_total, uint32_t nsamples_total,
int64_t fs_in, int64_t fs_in,
uint32_t sampled_ms, uint32_t sampled_ms,
uint32_t select_queue, uint32_t select_queue,
lv_16sc_t *all_fft_codes); lv_16sc_t *all_fft_codes,
uint32_t excludelimit);
~fpga_acquisition(); ~Fpga_Acquisition();
bool init(); bool init();
bool set_local_code(uint32_t PRN); bool set_local_code(uint32_t PRN);
bool free(); bool free();
void set_doppler_sweep(uint32_t num_sweeps); void set_doppler_sweep(uint32_t num_sweeps);
void set_doppler_sweep_debug(uint32_t num_sweeps, uint32_t doppler_index);
void run_acquisition(void); void run_acquisition(void);
void set_phase_step(uint32_t doppler_index); void set_phase_step(uint32_t doppler_index);
void read_acquisition_results(uint32_t *max_index, float *max_magnitude, void read_acquisition_results(uint32_t *max_index, float *firstpeak, float *secondpeak, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index, uint32_t *total_blk_exp);
uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index);
void block_samples(); void block_samples();
void unblock_samples(); void unblock_samples();
@ -86,6 +86,25 @@ public:
d_doppler_step = doppler_step; d_doppler_step = doppler_step;
} }
/*!
* \brief Reset the FPGA PL.
*/
void reset_acquisition(void);
/*!
* \brief read the scaling factor that has been used by the FFT-IFFT
*/
void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor);
void set_block_exp(uint32_t total_block_exp);
void write_local_code(void);
void configure_acquisition(void);
void close_device();
void open_device();
private: private:
int64_t d_fs_in; int64_t d_fs_in;
// data related to the hardware module and the driver // data related to the hardware module and the driver
@ -93,18 +112,18 @@ private:
volatile uint32_t *d_map_base; // driver memory map volatile uint32_t *d_map_base; // driver memory map
lv_16sc_t *d_all_fft_codes; // memory that contains all the code ffts lv_16sc_t *d_all_fft_codes; // memory that contains all the code ffts
uint32_t d_vector_length; // number of samples incluing padding and number of ms uint32_t d_vector_length; // number of samples incluing padding and number of ms
uint32_t d_excludelimit;
uint32_t d_nsamples_total; // number of samples including padding uint32_t d_nsamples_total; // number of samples including padding
uint32_t d_nsamples; // number of samples not including padding uint32_t d_nsamples; // number of samples not including padding
uint32_t d_select_queue; // queue selection uint32_t d_select_queue; // queue selection
std::string d_device_name; // HW device name std::string d_device_name; // HW device name
uint32_t d_doppler_max; // max doppler uint32_t d_doppler_max; // max doppler
uint32_t d_doppler_step; // doppler step uint32_t d_doppler_step; // doppler step
uint32_t d_PRN; // PRN
// FPGA private functions // FPGA private functions
uint32_t fpga_acquisition_test_register(uint32_t writeval); void fpga_acquisition_test_register(void);
void fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]); void fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]);
void configure_acquisition(); void read_result_valid(uint32_t *result_valid);
void reset_acquisition(void);
void close_device();
}; };
#endif /* GNSS_SDR_FPGA_ACQUISITION_H_ */ #endif /* GNSS_SDR_FPGA_ACQUISITION_H_ */

View File

@ -1,9 +1,9 @@
/*! /*!
* \file gnss_sdr_fpga_sample_counter.cc * \file gnss_sdr_fpga_sample_counter.cc
* \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks * \brief Simple block to report the current receiver time based on the output
* of the tracking or telemetry blocks
* \author Javier Arribas 2018. jarribas(at)cttc.es * \author Javier Arribas 2018. jarribas(at)cttc.es
* *
*
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
@ -53,10 +53,7 @@ gnss_sdr_fpga_sample_counter::gnss_sdr_fpga_sample_counter(
set_max_noutput_items(1); set_max_noutput_items(1);
interval_ms = _interval_ms; interval_ms = _interval_ms;
fs = _fs; fs = _fs;
//printf("CREATOR fs = %f\n", fs);
//printf("CREATOR interval_ms = %" PRIu32 "\n", interval_ms);
samples_per_output = std::round(fs * static_cast<double>(interval_ms) / 1e3); samples_per_output = std::round(fs * static_cast<double>(interval_ms) / 1e3);
//printf("CREATOR samples_per_output = %" PRIu32 "\n", samples_per_output);
//todo: Load here the hardware counter register with this amount of samples. It should produce an //todo: Load here the hardware counter register with this amount of samples. It should produce an
//interrupt every samples_per_output count. //interrupt every samples_per_output count.
//The hardware timer must keep always interrupting the PS. It must not wait for the interrupt to //The hardware timer must keep always interrupting the PS. It must not wait for the interrupt to
@ -122,7 +119,6 @@ int gnss_sdr_fpga_sample_counter::general_work(int noutput_items __attribute__((
uint32_t counter = wait_for_interrupt_and_read_counter(); uint32_t counter = wait_for_interrupt_and_read_counter();
uint64_t samples_passed = 2 * static_cast<uint64_t>(samples_per_output) - static_cast<uint64_t>(counter); // ellapsed samples uint64_t samples_passed = 2 * static_cast<uint64_t>(samples_per_output) - static_cast<uint64_t>(counter); // ellapsed samples
//printf("============================================ interrupter : samples_passed = %" PRIu64 "\n", samples_passed);
// Note: at this moment the sample counter is implemented as a sample counter that decreases to zero and then it is automatically // Note: at this moment the sample counter is implemented as a sample counter that decreases to zero and then it is automatically
// reloaded again and keeps counter. It is done in this way to minimize the logic in the FPGA and maximize the FPGA clock performance // reloaded again and keeps counter. It is done in this way to minimize the logic in the FPGA and maximize the FPGA clock performance
// (it takes less resources and latency in the FPGA to compare a number against a fixed value like zero than to compare it to a programmable // (it takes less resources and latency in the FPGA to compare a number against a fixed value like zero than to compare it to a programmable
@ -137,10 +133,6 @@ int gnss_sdr_fpga_sample_counter::general_work(int noutput_items __attribute__((
out[0].fs = fs; out[0].fs = fs;
if ((current_T_rx_ms % report_interval_ms) == 0) if ((current_T_rx_ms % report_interval_ms) == 0)
{ {
//printf("time to print sample_counter = %" PRIu64 "\n", sample_counter);
//printf("time to print current Tx ms : %" PRIu64 "\n", current_T_rx_ms);
//printf("time to print report_interval_ms : %" PRIu32 "\n", report_interval_ms);
//printf("time to print %f\n", (current_T_rx_ms % report_interval_ms));
current_s++; current_s++;
if ((current_s % 60) == 0) if ((current_s % 60) == 0)
{ {
@ -203,6 +195,7 @@ int gnss_sdr_fpga_sample_counter::general_work(int noutput_items __attribute__((
return 1; return 1;
} }
uint32_t gnss_sdr_fpga_sample_counter::test_register(uint32_t writeval) uint32_t gnss_sdr_fpga_sample_counter::test_register(uint32_t writeval)
{ {
uint32_t readval; uint32_t readval;
@ -214,20 +207,14 @@ uint32_t gnss_sdr_fpga_sample_counter::test_register(uint32_t writeval)
return readval; return readval;
} }
void gnss_sdr_fpga_sample_counter::configure_samples_per_output(uint32_t interval) void gnss_sdr_fpga_sample_counter::configure_samples_per_output(uint32_t interval)
{ {
// note : the counter is a 48-bit value in the HW. // note : the counter is a 48-bit value in the HW.
//printf("============================================ total counter - interrupted interval : %" PRIu32 "\n", interval);
//uint64_t temp_interval;
//temp_interval = (interval & static_cast<uint32_t>(0xFFFFFFFF));
//printf("LSW counter - interrupted interval : %" PRIu32 "\n", static_cast<uint32_t>(temp_interval));
//map_base[0] = static_cast<uint32_t>(temp_interval);
map_base[0] = interval - 1; map_base[0] = interval - 1;
//temp_interval = (interval >> 32) & static_cast<uint32_t>(0xFFFFFFFF);
//printf("MSbits counter - interrupted interval : %" PRIu32 "\n", static_cast<uint32_t>(temp_interval));
//map_base[1] = static_cast<uint32_t>(temp_interval); // writing the most significant bits also enables the interrupts
} }
void gnss_sdr_fpga_sample_counter::open_device() void gnss_sdr_fpga_sample_counter::open_device()
{ {
// open communication with HW accelerator // open communication with HW accelerator
@ -260,19 +247,20 @@ void gnss_sdr_fpga_sample_counter::open_device()
} }
} }
void gnss_sdr_fpga_sample_counter::close_device() void gnss_sdr_fpga_sample_counter::close_device()
{ {
//printf("=========================================== NOW closing device ...\n");
map_base[2] = 0; // disable the generation of the interrupt in the device map_base[2] = 0; // disable the generation of the interrupt in the device
auto *aux = const_cast<uint32_t *>(map_base); auto *aux = const_cast<uint32_t *>(map_base);
if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1) if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1)
{ {
printf("Failed to unmap memory uio\n"); std::cout << "Failed to unmap memory uio" << std::endl;
} }
close(fd); close(fd);
} }
uint32_t gnss_sdr_fpga_sample_counter::wait_for_interrupt_and_read_counter() uint32_t gnss_sdr_fpga_sample_counter::wait_for_interrupt_and_read_counter()
{ {
int32_t irq_count; int32_t irq_count;
@ -284,18 +272,15 @@ uint32_t gnss_sdr_fpga_sample_counter::wait_for_interrupt_and_read_counter()
write(fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t)); write(fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t));
// wait for interrupt // wait for interrupt
//printf("============================================ interrupter : going to wait for interupt\n");
nb = read(fd, &irq_count, sizeof(irq_count)); nb = read(fd, &irq_count, sizeof(irq_count));
//printf("============================================ interrupter : interrupt received\n");
//printf("interrupt received\n");
if (nb != sizeof(irq_count)) if (nb != sizeof(irq_count))
{ {
printf("acquisition module Read failed to retrieve 4 bytes!\n"); std::cout << "FPGA sample counter module read failed to retrieve 4 bytes!" << std::endl;
printf("acquisition module Interrupt number %d\n", irq_count); std::cout << "FPGA sample counter module interrupt number " << irq_count << std::endl;
} }
// acknowledge the interrupt // it is a rising edge interrupt, the interrupt does not need to be acknowledged
map_base[1] = 0; // writing anything to reg 1 acknowledges the interrupt //map_base[1] = 0; // writing anything to reg 1 acknowledges the interrupt
// add number of passed samples or read the current counter value for more accuracy // add number of passed samples or read the current counter value for more accuracy
counter = samples_per_output; //map_base[0]; counter = samples_per_output; //map_base[0];

View File

@ -1,6 +1,7 @@
/*! /*!
* \file gnss_sdr_fpga_sample_counter.h * \file gnss_sdr_fpga_sample_counter.h
* \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks * \brief Simple block to report the current receiver time based on the output
* of the tracking or telemetry blocks
* \author Javier Arribas 2018. jarribas(at)cttc.es * \author Javier Arribas 2018. jarribas(at)cttc.es
* *
* *
@ -28,16 +29,18 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
#ifndef GNSS_SDR_FPGA_sample_counter_H_
#define GNSS_SDR_FPGA_sample_counter_H_ #ifndef GNSS_SDR_GNSS_SDR_FPGA_SAMPLE_COUNTER_H_
#define GNSS_SDR_GNSS_SDR_FPGA_SAMPLE_COUNTER_H_
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <cstdint> #include <cstdint>
#include <string>
class gnss_sdr_fpga_sample_counter; class gnss_sdr_fpga_sample_counter;
typedef boost::shared_ptr<gnss_sdr_fpga_sample_counter> gnss_sdr_fpga_sample_counter_sptr; using gnss_sdr_fpga_sample_counter_sptr = boost::shared_ptr<gnss_sdr_fpga_sample_counter>;
gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms); gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms);
@ -68,7 +71,7 @@ private:
bool flag_enable_send_msg; bool flag_enable_send_msg;
int32_t fd; // driver descriptor int32_t fd; // driver descriptor
volatile uint32_t *map_base; // driver memory map volatile uint32_t *map_base; // driver memory map
std::string device_name = "/dev/uio26"; // HW device name std::string device_name = "/dev/uio2"; // HW device name
public: public:
friend gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms); friend gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms);
@ -78,4 +81,4 @@ public:
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
}; };
#endif /*GNSS_SDR_FPGA_sample_counter_H_*/ #endif // GNSS_SDR_GNSS_SDR_FPGA_SAMPLE_COUNTER_H_

View File

@ -37,7 +37,7 @@
class gnss_sdr_time_counter; class gnss_sdr_time_counter;
typedef boost::shared_ptr<gnss_sdr_time_counter> gnss_sdr_time_counter_sptr; using gnss_sdr_time_counter_sptr = boost::shared_ptr<gnss_sdr_time_counter>;
gnss_sdr_time_counter_sptr gnss_sdr_make_time_counter(); gnss_sdr_time_counter_sptr gnss_sdr_make_time_counter();

View File

@ -107,9 +107,9 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface* configura
} }
// turn switch to A/D position // turn switch to A/D position
std::string default_device_name = "/dev/uio13"; std::string default_device_name = "/dev/uio1";
std::string device_name = configuration->property(role + ".devicename", default_device_name); std::string device_name = configuration->property(role + ".devicename", default_device_name);
int switch_position = configuration->property(role + ".switch_position", 0); int32_t switch_position = configuration->property(role + ".switch_position", 0);
switch_fpga = std::make_shared<Fpga_Switch>(device_name); switch_fpga = std::make_shared<Fpga_Switch>(device_name);
switch_fpga->set_switch_position(switch_position); switch_fpga->set_switch_position(switch_position);
if (in_stream_ > 0) if (in_stream_ > 0)

View File

@ -2,7 +2,7 @@
* \file fpga_switch.cc * \file fpga_switch.cc
* \brief Switch that connects the HW accelerator queues to the analog front end or the DMA. * \brief Switch that connects the HW accelerator queues to the analog front end or the DMA.
* \authors <ul> * \authors <ul>
* <li> Marc Majoral, 2017. mmajoral(at)cttc.cat * <li> Marc Majoral, 2019. mmajoral(at)cttc.cat
* <li> Javier Arribas, 2015. jarribas(at)cttc.es * <li> Javier Arribas, 2015. jarribas(at)cttc.es
* </ul> * </ul>
* *
@ -43,7 +43,7 @@
// constants // constants
const size_t PAGE_SIZE = 0x10000; const size_t PAGE_SIZE = 0x10000;
const unsigned int TEST_REGISTER_TRACK_WRITEVAL = 0x55AA; const uint32_t TEST_REGISTER_TRACK_WRITEVAL = 0x55AA;
Fpga_Switch::Fpga_Switch(const std::string &device_name) Fpga_Switch::Fpga_Switch(const std::string &device_name)
{ {
@ -87,7 +87,7 @@ Fpga_Switch::~Fpga_Switch()
} }
void Fpga_Switch::set_switch_position(int switch_position) void Fpga_Switch::set_switch_position(int32_t switch_position)
{ {
d_map_base[0] = switch_position; d_map_base[0] = switch_position;
} }

View File

@ -2,7 +2,7 @@
* \file fpga_switch.h * \file fpga_switch.h
* \brief Switch that connects the HW accelerator queues to the analog front end or the DMA. * \brief Switch that connects the HW accelerator queues to the analog front end or the DMA.
* \authors <ul> * \authors <ul>
* <li> Marc Majoral, 2017. mmajoral(at)cttc.cat * <li> Marc Majoral, 2019. mmajoral(at)cttc.cat
* <li> Javier Arribas, 2016. jarribas(at)cttc.es * <li> Javier Arribas, 2016. jarribas(at)cttc.es
* </ul> * </ul>
* *
@ -46,7 +46,7 @@ class Fpga_Switch
public: public:
Fpga_Switch(const std::string& device_name); Fpga_Switch(const std::string& device_name);
~Fpga_Switch(); ~Fpga_Switch();
void set_switch_position(int switch_position); void set_switch_position(int32_t switch_position);
private: private:
int d_device_descriptor; // driver descriptor int d_device_descriptor; // driver descriptor

View File

@ -50,13 +50,13 @@ add_library(telemetry_decoder_gr_blocks
target_link_libraries(telemetry_decoder_gr_blocks target_link_libraries(telemetry_decoder_gr_blocks
PUBLIC PUBLIC
Gnuradio::runtime
Volkgnsssdr::volkgnsssdr
telemetry_decoder_libswiftcnav telemetry_decoder_libswiftcnav
telemetry_decoder_libs telemetry_decoder_libs
core_system_parameters core_system_parameters
PRIVATE Gnuradio::runtime
Volkgnsssdr::volkgnsssdr
Boost::boost Boost::boost
PRIVATE
Gflags::gflags Gflags::gflags
Glog::glog Glog::glog
) )

View File

@ -117,6 +117,7 @@ beidou_b1i_telemetry_decoder_cc::beidou_b1i_telemetry_decoder_cc(
d_subframe_symbols = static_cast<double *>(volk_gnsssdr_malloc(BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS * sizeof(double), volk_gnsssdr_get_alignment())); d_subframe_symbols = static_cast<double *>(volk_gnsssdr_malloc(BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS * sizeof(double), volk_gnsssdr_get_alignment()));
d_required_symbols = BEIDOU_DNAV_SUBFRAME_SYMBOLS * d_samples_per_symbol + d_samples_per_preamble; d_required_symbols = BEIDOU_DNAV_SUBFRAME_SYMBOLS * d_samples_per_symbol + d_samples_per_preamble;
d_symbol_history.set_capacity(d_required_symbols + 1);
// Generic settings // Generic settings
d_sample_counter = 0; d_sample_counter = 0;
d_stat = 0; d_stat = 0;
@ -316,12 +317,8 @@ void beidou_b1i_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satell
volk_gnsssdr_free(d_secondary_code_symbols); volk_gnsssdr_free(d_secondary_code_symbols);
volk_gnsssdr_free(d_subframe_symbols); volk_gnsssdr_free(d_subframe_symbols);
d_samples_per_symbol = (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS) / BEIDOU_D2NAV_SYMBOL_RATE_SPS;
d_symbols_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS;
d_samples_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS * d_samples_per_symbol;
d_secondary_code_symbols = nullptr; d_secondary_code_symbols = nullptr;
d_preamble_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); d_preamble_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment()));
d_preamble_period_samples = BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS * d_samples_per_symbol;
// Setting samples of preamble code // Setting samples of preamble code
int32_t n = 0; int32_t n = 0;
@ -401,7 +398,7 @@ int beidou_b1i_telemetry_decoder_cc::general_work(int noutput_items __attribute_
//******* preamble correlation ******** //******* preamble correlation ********
for (int32_t i = 0; i < d_samples_per_preamble; i++) for (int32_t i = 0; i < d_samples_per_preamble; i++)
{ {
if (d_symbol_history.at(i) < 0) // symbols clipping if (d_symbol_history[i] < 0) // symbols clipping
{ {
corr_value -= d_preamble_samples[i]; corr_value -= d_preamble_samples[i];
} }
@ -579,11 +576,6 @@ int beidou_b1i_telemetry_decoder_cc::general_work(int noutput_items __attribute_
} }
} }
// remove used symbols from history
if (d_symbol_history.size() > d_required_symbols)
{
d_symbol_history.pop_front();
}
// 3. Make the output (copy the object contents to the GNURadio reserved memory) // 3. Make the output (copy the object contents to the GNURadio reserved memory)
*out[0] = current_symbol; *out[0] = current_symbol;

View File

@ -42,6 +42,7 @@
#include "beidou_dnav_utc_model.h" #include "beidou_dnav_utc_model.h"
#include "gnss_satellite.h" #include "gnss_satellite.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include <boost/circular_buffer.hpp>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <fstream> #include <fstream>
#include <string> #include <string>
@ -94,7 +95,7 @@ private:
uint32_t d_required_symbols; uint32_t d_required_symbols;
// Storage for incoming data // Storage for incoming data
std::deque<float> d_symbol_history; boost::circular_buffer<float> d_symbol_history;
// Variables for internal functionality // Variables for internal functionality
uint64_t d_sample_counter; // Sample counter as an index (1,2,3,..etc) indicating number of samples processed uint64_t d_sample_counter; // Sample counter as an index (1,2,3,..etc) indicating number of samples processed

View File

@ -52,25 +52,6 @@ galileo_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, int frame_typ
} }
void galileo_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits)
{
Viterbi(page_part_bits, out0, state0, out1, state1,
page_part_symbols, KK, nn, DataLength);
}
void galileo_telemetry_decoder_cc::deinterleaver(int32_t rows, int32_t cols, const double *in, double *out)
{
for (int32_t r = 0; r < rows; r++)
{
for (int32_t c = 0; c < cols; c++)
{
out[c * rows + r] = in[r * cols + c];
}
}
}
galileo_telemetry_decoder_cc::galileo_telemetry_decoder_cc( galileo_telemetry_decoder_cc::galileo_telemetry_decoder_cc(
const Gnss_Satellite &satellite, int frame_type, const Gnss_Satellite &satellite, int frame_type,
bool dump) : gr::block("galileo_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), bool dump) : gr::block("galileo_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
@ -216,6 +197,8 @@ galileo_telemetry_decoder_cc::galileo_telemetry_decoder_cc(
d_channel = 0; d_channel = 0;
flag_TOW_set = false; flag_TOW_set = false;
d_symbol_history.set_capacity(d_required_symbols + 1);
// vars for Viterbi decoder // vars for Viterbi decoder
int32_t max_states = 1 << mm; // 2^mm int32_t max_states = 1 << mm; // 2^mm
g_encoder[0] = 121; // Polynomial G1 g_encoder[0] = 121; // Polynomial G1
@ -256,6 +239,25 @@ galileo_telemetry_decoder_cc::~galileo_telemetry_decoder_cc()
} }
void galileo_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits)
{
Viterbi(page_part_bits, out0, state0, out1, state1,
page_part_symbols, KK, nn, DataLength);
}
void galileo_telemetry_decoder_cc::deinterleaver(int32_t rows, int32_t cols, const double *in, double *out)
{
for (int32_t r = 0; r < rows; r++)
{
for (int32_t c = 0; c < cols; c++)
{
out[c * rows + r] = in[r * cols + c];
}
}
}
void galileo_telemetry_decoder_cc::decode_INAV_word(double *page_part_symbols, int32_t frame_length) void galileo_telemetry_decoder_cc::decode_INAV_word(double *page_part_symbols, int32_t frame_length)
{ {
// 1. De-interleave // 1. De-interleave
@ -473,11 +475,10 @@ int galileo_telemetry_decoder_cc::general_work(int noutput_items __attribute__((
if (d_symbol_history.size() > d_required_symbols) if (d_symbol_history.size() > d_required_symbols)
{ {
// TODO Optimize me!
// ******* preamble correlation ******** // ******* preamble correlation ********
for (int32_t i = 0; i < d_samples_per_preamble; i++) for (int32_t i = 0; i < d_samples_per_preamble; i++)
{ {
if (d_symbol_history.at(i) < 0.0) // symbols clipping if (d_symbol_history[i] < 0.0) // symbols clipping
{ {
corr_value -= d_preamble_samples[i]; corr_value -= d_preamble_samples[i];
} }
@ -717,13 +718,6 @@ int galileo_telemetry_decoder_cc::general_work(int noutput_items __attribute__((
} }
} }
// remove used symbols from history
// todo: Use circular buffer here
if (d_symbol_history.size() > d_required_symbols)
{
d_symbol_history.pop_front();
}
switch (d_frame_type) switch (d_frame_type)
{ {
case 1: // INAV case 1: // INAV

View File

@ -43,11 +43,11 @@
#include "galileo_utc_model.h" #include "galileo_utc_model.h"
#include "gnss_satellite.h" #include "gnss_satellite.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include <boost/circular_buffer.hpp>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <fstream> #include <fstream>
#include <string> #include <string>
class galileo_telemetry_decoder_cc; class galileo_telemetry_decoder_cc;
using galileo_telemetry_decoder_cc_sptr = boost::shared_ptr<galileo_telemetry_decoder_cc>; using galileo_telemetry_decoder_cc_sptr = boost::shared_ptr<galileo_telemetry_decoder_cc>;
@ -95,7 +95,7 @@ private:
uint32_t d_frame_length_symbols; uint32_t d_frame_length_symbols;
double *d_page_part_symbols; double *d_page_part_symbols;
std::deque<float> d_symbol_history; boost::circular_buffer<float> d_symbol_history;
uint64_t d_sample_counter; uint64_t d_sample_counter;
uint64_t d_preamble_index; uint64_t d_preamble_index;

View File

@ -89,6 +89,8 @@ glonass_l1_ca_telemetry_decoder_cc::glonass_l1_ca_telemetry_decoder_cc(
n++; n++;
} }
} }
d_symbol_history.set_capacity(GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS);
d_sample_counter = 0ULL; d_sample_counter = 0ULL;
d_stat = 0; d_stat = 0;
d_preamble_index = 0ULL; d_preamble_index = 0ULL;
@ -276,14 +278,14 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
consume_each(1); consume_each(1);
d_flag_preamble = false; d_flag_preamble = false;
uint32_t required_symbols = GLONASS_GNAV_STRING_SYMBOLS;
if (d_symbol_history.size() > required_symbols) if (d_symbol_history.size() == d_symbols_per_preamble)
{ {
// ******* preamble correlation ******** // ******* preamble correlation ********
for (int32_t i = 0; i < d_symbols_per_preamble; i++) int i = 0;
for (const auto &iter : d_symbol_history)
{ {
if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping if (iter.Prompt_I < 0.0) // symbols clipping
{ {
corr_value -= d_preambles_symbols[i]; corr_value -= d_preambles_symbols[i];
} }
@ -291,6 +293,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
{ {
corr_value += d_preambles_symbols[i]; corr_value += d_preambles_symbols[i];
} }
i++;
} }
} }
@ -304,7 +307,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
LOG(INFO) << "Preamble detection for GLONASS L1 C/A SAT " << this->d_satellite; LOG(INFO) << "Preamble detection for GLONASS L1 C/A SAT " << this->d_satellite;
// Enter into frame pre-detection status // Enter into frame pre-detection status
d_stat = 1; d_stat = 1;
d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the preamble sample stamp d_preamble_time_samples = d_symbol_history[0].Tracking_sample_counter; // record the preamble sample stamp
} }
} }
else if (d_stat == 1) // possible preamble lock else if (d_stat == 1) // possible preamble lock
@ -314,7 +317,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
// check preamble separation // check preamble separation
preamble_diff = static_cast<int32_t>(d_sample_counter - d_preamble_index); preamble_diff = static_cast<int32_t>(d_sample_counter - d_preamble_index);
// Record the PRN start sample index associated to the preamble // Record the PRN start sample index associated to the preamble
d_preamble_time_samples = static_cast<double>(d_symbol_history.at(0).Tracking_sample_counter); d_preamble_time_samples = static_cast<double>(d_symbol_history[0].Tracking_sample_counter);
if (abs(preamble_diff - GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) == 0) if (abs(preamble_diff - GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) == 0)
{ {
// try to decode frame // try to decode frame
@ -366,7 +369,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
{ {
d_flag_frame_sync = true; d_flag_frame_sync = true;
DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at "
<< d_symbol_history.at(0).Tracking_sample_counter << " [samples]"; << d_symbol_history[0].Tracking_sample_counter << " [samples]";
} }
} }
else else
@ -437,11 +440,6 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
} }
} }
// remove used symbols from history
if (d_symbol_history.size() > required_symbols)
{
d_symbol_history.pop_front();
}
// 3. Make the output (copy the object contents to the GNURadio reserved memory) // 3. Make the output (copy the object contents to the GNURadio reserved memory)
*out[0] = current_symbol; *out[0] = current_symbol;

View File

@ -41,6 +41,7 @@
#include "glonass_gnav_utc_model.h" #include "glonass_gnav_utc_model.h"
#include "gnss_satellite.h" #include "gnss_satellite.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include <boost/circular_buffer.hpp>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <fstream> #include <fstream>
#include <string> #include <string>
@ -88,7 +89,7 @@ private:
int32_t d_symbols_per_preamble; int32_t d_symbols_per_preamble;
//!< Storage for incoming data //!< Storage for incoming data
std::deque<Gnss_Synchro> d_symbol_history; boost::circular_buffer<Gnss_Synchro> d_symbol_history;
//!< Variables for internal functionality //!< Variables for internal functionality
uint64_t d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed uint64_t d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed

View File

@ -89,6 +89,8 @@ glonass_l2_ca_telemetry_decoder_cc::glonass_l2_ca_telemetry_decoder_cc(
n++; n++;
} }
} }
d_symbol_history.set_capacity(GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS);
d_sample_counter = 0ULL; d_sample_counter = 0ULL;
d_stat = 0; d_stat = 0;
d_preamble_index = 0ULL; d_preamble_index = 0ULL;
@ -276,14 +278,14 @@ int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
consume_each(1); consume_each(1);
d_flag_preamble = false; d_flag_preamble = false;
uint32_t required_symbols = GLONASS_GNAV_STRING_SYMBOLS;
if (d_symbol_history.size() > required_symbols) if (d_symbol_history.size() == GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS)
{ {
// ******* preamble correlation ******** // ******* preamble correlation ********
for (int32_t i = 0; i < d_symbols_per_preamble; i++) int i = 0;
for (const auto &iter : d_symbol_history)
{ {
if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping if (iter.Prompt_I < 0.0) // symbols clipping
{ {
corr_value -= d_preambles_symbols[i]; corr_value -= d_preambles_symbols[i];
} }
@ -291,6 +293,7 @@ int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
{ {
corr_value += d_preambles_symbols[i]; corr_value += d_preambles_symbols[i];
} }
i++;
} }
} }
@ -304,7 +307,7 @@ int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
LOG(INFO) << "Preamble detection for GLONASS L2 C/A SAT " << this->d_satellite; LOG(INFO) << "Preamble detection for GLONASS L2 C/A SAT " << this->d_satellite;
// Enter into frame pre-detection status // Enter into frame pre-detection status
d_stat = 1; d_stat = 1;
d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the preamble sample stamp d_preamble_time_samples = d_symbol_history[0].Tracking_sample_counter; // record the preamble sample stamp
} }
} }
else if (d_stat == 1) // possible preamble lock else if (d_stat == 1) // possible preamble lock
@ -314,7 +317,7 @@ int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
// check preamble separation // check preamble separation
preamble_diff = static_cast<int32_t>(d_sample_counter - d_preamble_index); preamble_diff = static_cast<int32_t>(d_sample_counter - d_preamble_index);
// Record the PRN start sample index associated to the preamble // Record the PRN start sample index associated to the preamble
d_preamble_time_samples = static_cast<double>(d_symbol_history.at(0).Tracking_sample_counter); d_preamble_time_samples = static_cast<double>(d_symbol_history[0].Tracking_sample_counter);
if (abs(preamble_diff - GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) == 0) if (abs(preamble_diff - GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) == 0)
{ {
// try to decode frame // try to decode frame
@ -366,7 +369,7 @@ int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
{ {
d_flag_frame_sync = true; d_flag_frame_sync = true;
DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at "
<< d_symbol_history.at(0).Tracking_sample_counter << " [samples]"; << d_symbol_history[0].Tracking_sample_counter << " [samples]";
} }
} }
else else
@ -437,11 +440,6 @@ int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu
} }
} }
// remove used symbols from history
if (d_symbol_history.size() > required_symbols)
{
d_symbol_history.pop_front();
}
// 3. Make the output (copy the object contents to the GNURadio reserved memory) // 3. Make the output (copy the object contents to the GNURadio reserved memory)
*out[0] = current_symbol; *out[0] = current_symbol;

View File

@ -40,6 +40,7 @@
#include "glonass_gnav_utc_model.h" #include "glonass_gnav_utc_model.h"
#include "gnss_satellite.h" #include "gnss_satellite.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include <boost/circular_buffer.hpp>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <fstream> #include <fstream>
#include <string> #include <string>
@ -86,7 +87,7 @@ private:
int32_t d_symbols_per_preamble; int32_t d_symbols_per_preamble;
//!< Storage for incoming data //!< Storage for incoming data
std::deque<Gnss_Synchro> d_symbol_history; boost::circular_buffer<Gnss_Synchro> d_symbol_history;
//!< Variables for internal functionality //!< Variables for internal functionality
uint64_t d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed uint64_t d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed

View File

@ -343,7 +343,7 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__
{ {
if (iter.Flag_valid_symbol_output == true) if (iter.Flag_valid_symbol_output == true)
{ {
if (iter.Prompt_I < 0) // symbols clipping if (iter.Prompt_I < 0.0) // symbols clipping
{ {
corr_value -= d_preambles_symbols[i]; corr_value -= d_preambles_symbols[i];
} }

View File

@ -32,6 +32,7 @@
#define GNSS_SDR_GPS_L2C_TELEMETRY_DECODER_CC_H #define GNSS_SDR_GPS_L2C_TELEMETRY_DECODER_CC_H
#include "GPS_L2C.h"
#include "gnss_satellite.h" #include "gnss_satellite.h"
#include "gps_cnav_ephemeris.h" #include "gps_cnav_ephemeris.h"
#include "gps_cnav_iono.h" #include "gps_cnav_iono.h"
@ -39,13 +40,11 @@
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <algorithm> // for copy #include <algorithm> // for copy
#include <cstdint> #include <cstdint>
#include <deque>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <utility> // for pair #include <utility> // for pair
#include <vector> #include <vector>
extern "C" extern "C"
{ {
#include "bits.h" #include "bits.h"
@ -53,7 +52,6 @@ extern "C"
#include "edc.h" #include "edc.h"
} }
#include "GPS_L2C.h"
class gps_l2c_telemetry_decoder_cc; class gps_l2c_telemetry_decoder_cc;

View File

@ -66,6 +66,8 @@ gps_l5_telemetry_decoder_cc::gps_l5_telemetry_decoder_cc(
d_flag_valid_word = false; d_flag_valid_word = false;
d_TOW_at_current_symbol_ms = 0U; d_TOW_at_current_symbol_ms = 0U;
d_TOW_at_Preamble_ms = 0U; d_TOW_at_Preamble_ms = 0U;
sym_hist.set_capacity(GPS_L5I_NH_CODE_LENGTH);
// initialize the CNAV frame decoder (libswiftcnav) // initialize the CNAV frame decoder (libswiftcnav)
cnav_msg_decoder_init(&d_cnav_decoder); cnav_msg_decoder_init(&d_cnav_decoder);
for (int32_t aux = 0; aux < GPS_L5I_NH_CODE_LENGTH; aux++) for (int32_t aux = 0; aux < GPS_L5I_NH_CODE_LENGTH; aux++)
@ -158,7 +160,7 @@ int gps_l5_telemetry_decoder_cc::general_work(int noutput_items __attribute__((u
{ {
for (int32_t i = 0; i < GPS_L5I_NH_CODE_LENGTH; i++) for (int32_t i = 0; i < GPS_L5I_NH_CODE_LENGTH; i++)
{ {
if ((bits_NH[i] * sym_hist.at(i)) > 0.0) if ((bits_NH[i] * sym_hist[i]) > 0.0)
{ {
corr_NH += 1; corr_NH += 1;
} }
@ -183,7 +185,6 @@ int gps_l5_telemetry_decoder_cc::general_work(int noutput_items __attribute__((u
} }
else else
{ {
sym_hist.pop_front();
sync_NH = false; sync_NH = false;
new_sym = false; new_sym = false;
} }

View File

@ -31,12 +31,13 @@
#define GNSS_SDR_GPS_L5_TELEMETRY_DECODER_CC_H #define GNSS_SDR_GPS_L5_TELEMETRY_DECODER_CC_H
#include "GPS_L5.h"
#include "gnss_satellite.h" #include "gnss_satellite.h"
#include "gps_cnav_navigation_message.h" #include "gps_cnav_navigation_message.h"
#include <boost/circular_buffer.hpp>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
#include <deque>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <utility> #include <utility>
@ -49,7 +50,6 @@ extern "C"
#include "edc.h" #include "edc.h"
} }
#include "GPS_L5.h"
class gps_l5_telemetry_decoder_cc; class gps_l5_telemetry_decoder_cc;
@ -90,8 +90,8 @@ private:
bool d_flag_valid_word; bool d_flag_valid_word;
Gps_CNAV_Navigation_Message d_CNAV_Message; Gps_CNAV_Navigation_Message d_CNAV_Message;
double bits_NH[GPS_L5I_NH_CODE_LENGTH]{}; float bits_NH[GPS_L5I_NH_CODE_LENGTH]{};
std::deque<double> sym_hist; boost::circular_buffer<float> sym_hist;
bool sync_NH; bool sync_NH;
bool new_sym; bool new_sym;
}; };

View File

@ -1,7 +1,8 @@
/*! /*!
* \file galileo_e1_dll_pll_veml_tracking.cc * \file galileo_e1_dll_pll_veml_tracking_fpga.cc
* \brief Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block * \brief Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block
* to a TrackingInterface for Galileo E1 signals * to a TrackingInterface for Galileo E1 signals for the FPGA
* \author Marc Majoral, 2019. mmajoral(at)cttc.cat
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
* *
* Code DLL + carrier PLL according to the algorithms described in: * Code DLL + carrier PLL according to the algorithms described in:
@ -11,7 +12,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -42,8 +43,6 @@
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include <glog/logging.h> #include <glog/logging.h>
//#define NUM_PRNs_GALILEO_E1 50
using google::LogMessage; using google::LogMessage;
void GalileoE1DllPllVemlTrackingFpga::stop_tracking() void GalileoE1DllPllVemlTrackingFpga::stop_tracking()
@ -54,14 +53,13 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
ConfigurationInterface* configuration, const std::string& role, ConfigurationInterface* configuration, const std::string& role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{ {
//dllpllconf_t trk_param;
Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga();
DLOG(INFO) << "role " << role; DLOG(INFO) << "role " << role;
//################# CONFIGURATION PARAMETERS ######################## //################# CONFIGURATION PARAMETERS ########################
std::string default_item_type = "gr_complex"; std::string default_item_type = "gr_complex";
std::string item_type = configuration->property(role + ".item_type", default_item_type); std::string item_type = configuration->property(role + ".item_type", default_item_type);
int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); int32_t fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); int32_t fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
trk_param_fpga.fs_in = fs_in; trk_param_fpga.fs_in = fs_in;
bool dump = configuration->property(role + ".dump", false); bool dump = configuration->property(role + ".dump", false);
trk_param_fpga.dump = dump; trk_param_fpga.dump = dump;
@ -80,7 +78,7 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
trk_param_fpga.pll_bw_narrow_hz = pll_bw_narrow_hz; 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); 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; trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz;
int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); int32_t extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1);
float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.15); 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; 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); float very_early_late_space_chips = configuration->property(role + ".very_early_late_space_chips", 0.6);
@ -107,18 +105,18 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
trk_param_fpga.track_pilot = track_pilot; trk_param_fpga.track_pilot = track_pilot;
d_track_pilot = track_pilot; d_track_pilot = track_pilot;
trk_param_fpga.extend_correlation_symbols = extend_correlation_symbols; trk_param_fpga.extend_correlation_symbols = extend_correlation_symbols;
int vector_length = std::round(fs_in / (GALILEO_E1_CODE_CHIP_RATE_HZ / GALILEO_E1_B_CODE_LENGTH_CHIPS)); int32_t 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.vector_length = vector_length;
trk_param_fpga.system = 'E'; trk_param_fpga.system = 'E';
char sig_[3] = "1B"; char sig_[3] = "1B";
std::memcpy(trk_param_fpga.signal, sig_, 3); std::memcpy(trk_param_fpga.signal, sig_, 3);
int cn0_samples = configuration->property(role + ".cn0_samples", 20); int32_t cn0_samples = configuration->property(role + ".cn0_samples", 20);
if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples;
trk_param_fpga.cn0_samples = cn0_samples; trk_param_fpga.cn0_samples = cn0_samples;
int cn0_min = configuration->property(role + ".cn0_min", 25); int32_t cn0_min = configuration->property(role + ".cn0_min", 25);
if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min;
trk_param_fpga.cn0_min = cn0_min; trk_param_fpga.cn0_min = cn0_min;
int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); int32_t max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail;
trk_param_fpga.max_lock_fail = max_lock_fail; trk_param_fpga.max_lock_fail = max_lock_fail;
double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85);
@ -129,63 +127,51 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
std::string default_device_name = "/dev/uio"; std::string default_device_name = "/dev/uio";
std::string device_name = configuration->property(role + ".devicename", default_device_name); std::string device_name = configuration->property(role + ".devicename", default_device_name);
trk_param_fpga.device_name = device_name; trk_param_fpga.device_name = device_name;
unsigned int device_base = configuration->property(role + ".device_base", 1); uint32_t device_base = configuration->property(role + ".device_base", 15);
trk_param_fpga.device_base = device_base; trk_param_fpga.device_base = device_base;
//unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 1);
trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> 5 correlators trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> 5 correlators
//################# PRE-COMPUTE ALL THE CODES ################# //################# PRE-COMPUTE ALL THE CODES #################
unsigned int code_samples_per_chip = 2; uint32_t code_samples_per_chip = 2;
d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(GALILEO_E1_B_CODE_LENGTH_CHIPS) * code_samples_per_chip * GALILEO_E1_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); d_ca_codes = static_cast<int32_t*>(volk_gnsssdr_malloc(static_cast<int32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS) * code_samples_per_chip * GALILEO_E1_NUMBER_OF_CODES * sizeof(int32_t), volk_gnsssdr_get_alignment()));
float* ca_codes_f; float* ca_codes_f;
float* data_codes_f; float* data_codes_f;
if (trk_param_fpga.track_pilot)
{
d_data_codes = static_cast<int*>(volk_gnsssdr_malloc((static_cast<unsigned int>(GALILEO_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * GALILEO_E1_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment()));
}
ca_codes_f = static_cast<float*>(volk_gnsssdr_malloc(static_cast<int>(GALILEO_E1_B_CODE_LENGTH_CHIPS) * code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment()));
if (trk_param_fpga.track_pilot) if (trk_param_fpga.track_pilot)
{ {
data_codes_f = static_cast<float*>(volk_gnsssdr_malloc((static_cast<unsigned int>(GALILEO_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment())); d_data_codes = static_cast<int32_t*>(volk_gnsssdr_malloc((static_cast<uint32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * GALILEO_E1_NUMBER_OF_CODES * sizeof(int32_t), volk_gnsssdr_get_alignment()));
}
ca_codes_f = static_cast<float*>(volk_gnsssdr_malloc(static_cast<int32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS) * code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment()));
if (trk_param_fpga.track_pilot)
{
data_codes_f = static_cast<float*>(volk_gnsssdr_malloc((static_cast<uint32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment()));
} }
//printf("pppppppp trk_param_fpga.track_pilot = %d\n", trk_param_fpga.track_pilot); for (uint32_t PRN = 1; PRN <= GALILEO_E1_NUMBER_OF_CODES; PRN++)
//int kk;
for (unsigned int PRN = 1; PRN <= GALILEO_E1_NUMBER_OF_CODES; PRN++)
{ {
char data_signal[3] = "1B"; char data_signal[3] = "1B";
if (trk_param_fpga.track_pilot) if (trk_param_fpga.track_pilot)
{ {
//printf("yes tracking pilot !!!!!!!!!!!!!!!\n");
char pilot_signal[3] = "1C"; char pilot_signal[3] = "1C";
galileo_e1_code_gen_sinboc11_float(ca_codes_f, pilot_signal, PRN); galileo_e1_code_gen_sinboc11_float(ca_codes_f, pilot_signal, PRN);
galileo_e1_code_gen_sinboc11_float(data_codes_f, data_signal, PRN); galileo_e1_code_gen_sinboc11_float(data_codes_f, data_signal, PRN);
for (unsigned int s = 0; s < 2 * GALILEO_E1_B_CODE_LENGTH_CHIPS; s++) for (uint32_t s = 0; s < 2 * 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_ca_codes[static_cast<int32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS) * 2 * (PRN - 1) + s] = static_cast<int32_t>(ca_codes_f[s]);
d_data_codes[static_cast<int>(GALILEO_E1_B_CODE_LENGTH_CHIPS) * 2 * (PRN - 1) + s] = static_cast<int>(data_codes_f[s]); d_data_codes[static_cast<int32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS) * 2 * (PRN - 1) + s] = static_cast<int32_t>(data_codes_f[s]);
//printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast<int>(GALILEO_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]);
} }
//printf("\n next \n");
//scanf ("%d",&kk);
} }
else else
{ {
//printf("no tracking pilot\n");
galileo_e1_code_gen_sinboc11_float(ca_codes_f, data_signal, PRN); galileo_e1_code_gen_sinboc11_float(ca_codes_f, data_signal, PRN);
for (unsigned int s = 0; s < 2 * GALILEO_E1_B_CODE_LENGTH_CHIPS; s++) for (uint32_t s = 0; s < 2 * 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_ca_codes[static_cast<int32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS) * 2 * (PRN - 1) + s] = static_cast<int32_t>(ca_codes_f[s]);
//printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast<int>(GALILEO_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]);
} }
//printf("\n next \n");
//scanf ("%d",&kk);
} }
} }
@ -216,7 +202,6 @@ GalileoE1DllPllVemlTrackingFpga::~GalileoE1DllPllVemlTrackingFpga()
void GalileoE1DllPllVemlTrackingFpga::start_tracking() void GalileoE1DllPllVemlTrackingFpga::start_tracking()
{ {
//tracking_->start_tracking();
tracking_fpga_sc->start_tracking(); tracking_fpga_sc->start_tracking();
} }
@ -227,14 +212,12 @@ void GalileoE1DllPllVemlTrackingFpga::start_tracking()
void GalileoE1DllPllVemlTrackingFpga::set_channel(unsigned int channel) void GalileoE1DllPllVemlTrackingFpga::set_channel(unsigned int channel)
{ {
channel_ = channel; channel_ = channel;
//tracking_->set_channel(channel);
tracking_fpga_sc->set_channel(channel); tracking_fpga_sc->set_channel(channel);
} }
void GalileoE1DllPllVemlTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) 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); tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro);
} }
@ -259,13 +242,11 @@ void GalileoE1DllPllVemlTrackingFpga::disconnect(gr::top_block_sptr top_block)
gr::basic_block_sptr GalileoE1DllPllVemlTrackingFpga::get_left_block() gr::basic_block_sptr GalileoE1DllPllVemlTrackingFpga::get_left_block()
{ {
//return tracking_;
return tracking_fpga_sc; return tracking_fpga_sc;
} }
gr::basic_block_sptr GalileoE1DllPllVemlTrackingFpga::get_right_block() gr::basic_block_sptr GalileoE1DllPllVemlTrackingFpga::get_right_block()
{ {
//return tracking_;
return tracking_fpga_sc; return tracking_fpga_sc;
} }

View File

@ -1,7 +1,8 @@
/*! /*!
* \file galileo_e1_dll_pll_veml_tracking.h * \file galileo_e1_dll_pll_veml_tracking_fpga.h
* \brief Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block * \brief Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block
* to a TrackingInterface for Galileo E1 signals * to a TrackingInterface for Galileo E1 signals for the FPGA
* \author Marc Majoral, 2019. mmajoral(at)cttc.cat
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
* *
* Code DLL + carrier PLL according to the algorithms described in: * Code DLL + carrier PLL according to the algorithms described in:
@ -11,7 +12,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -63,7 +64,7 @@ public:
return role_; return role_;
} }
//! Returns "Galileo_E1_DLL_PLL_VEML_Tracking" //! Returns "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"
inline std::string implementation() override inline std::string implementation() override
{ {
return "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"; return "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga";
@ -100,15 +101,14 @@ public:
private: private:
//dll_pll_veml_tracking_sptr tracking_;
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
size_t item_size_; size_t item_size_;
unsigned int channel_; uint32_t channel_;
std::string role_; std::string role_;
unsigned int in_streams_; uint32_t in_streams_;
unsigned int out_streams_; uint32_t out_streams_;
int* d_ca_codes; int32_t* d_ca_codes;
int* d_data_codes; int32_t* d_data_codes;
bool d_track_pilot; bool d_track_pilot;
}; };

View File

@ -1,19 +1,20 @@
/*! /*!
* \file galileo_e5a_dll_pll_tracking.cc * \file galileo_e5a_dll_pll_tracking_fpga.cc
* \brief Adapts a code DLL + carrier PLL * \brief Adapts a code DLL + carrier PLL
* tracking block to a TrackingInterface for Galileo E5a signals * tracking block to a TrackingInterface for Galileo E5a signals for the FPGA
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Galileo E5a data and pilot Signals * Galileo E5a data and pilot Signals for the FPGA
* \author Marc Sales, 2014. marcsales92(at)gmail.com * \author Marc Sales, 2014. marcsales92(at)gmail.com
* \based on work from: * \based on work from:
* <ul> * <ul>
* <li> Marc Majoral, 2019. mmajoral(at)cttc.cat
* <li> Javier Arribas, 2011. jarribas(at)cttc.es * <li> Javier Arribas, 2011. jarribas(at)cttc.es
* <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com * <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
* </ul> * </ul>
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -54,16 +55,13 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga(
ConfigurationInterface *configuration, const std::string &role, ConfigurationInterface *configuration, const std::string &role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{ {
//printf("creating the E5A tracking");
Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga();
DLOG(INFO) << "role " << role; DLOG(INFO) << "role " << role;
//################# CONFIGURATION PARAMETERS ######################## //################# CONFIGURATION PARAMETERS ########################
std::string default_item_type = "gr_complex"; std::string default_item_type = "gr_complex";
std::string item_type = configuration->property(role + ".item_type", default_item_type); std::string item_type = configuration->property(role + ".item_type", default_item_type);
int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 12000000); int32_t fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 12000000);
int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); int32_t fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
trk_param_fpga.fs_in = fs_in; trk_param_fpga.fs_in = fs_in;
bool dump = configuration->property(role + ".dump", false); bool dump = configuration->property(role + ".dump", false);
trk_param_fpga.dump = dump; trk_param_fpga.dump = dump;
@ -84,9 +82,9 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga(
trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz; trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz;
float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); 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; trk_param_fpga.early_late_space_chips = early_late_space_chips;
int vector_length = std::round(fs_in / (GALILEO_E5A_CODE_CHIP_RATE_HZ / GALILEO_E5A_CODE_LENGTH_CHIPS)); int32_t vector_length = std::round(fs_in / (GALILEO_E5A_CODE_CHIP_RATE_HZ / GALILEO_E5A_CODE_LENGTH_CHIPS));
trk_param_fpga.vector_length = vector_length; trk_param_fpga.vector_length = vector_length;
int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); int32_t extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1);
float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15); 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; trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips;
bool track_pilot = configuration->property(role + ".track_pilot", false); bool track_pilot = configuration->property(role + ".track_pilot", false);
@ -112,13 +110,13 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga(
trk_param_fpga.system = 'E'; trk_param_fpga.system = 'E';
char sig_[3] = "5X"; char sig_[3] = "5X";
std::memcpy(trk_param_fpga.signal, sig_, 3); std::memcpy(trk_param_fpga.signal, sig_, 3);
int cn0_samples = configuration->property(role + ".cn0_samples", 20); int32_t cn0_samples = configuration->property(role + ".cn0_samples", 20);
if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples;
trk_param_fpga.cn0_samples = cn0_samples; trk_param_fpga.cn0_samples = cn0_samples;
int cn0_min = configuration->property(role + ".cn0_min", 25); int32_t cn0_min = configuration->property(role + ".cn0_min", 25);
if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min;
trk_param_fpga.cn0_min = cn0_min; trk_param_fpga.cn0_min = cn0_min;
int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); int32_t max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail;
trk_param_fpga.max_lock_fail = max_lock_fail; trk_param_fpga.max_lock_fail = max_lock_fail;
double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85);
@ -129,93 +127,53 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga(
std::string default_device_name = "/dev/uio"; std::string default_device_name = "/dev/uio";
std::string device_name = configuration->property(role + ".devicename", default_device_name); std::string device_name = configuration->property(role + ".devicename", default_device_name);
trk_param_fpga.device_name = device_name; trk_param_fpga.device_name = device_name;
unsigned int device_base = configuration->property(role + ".device_base", 1); uint32_t device_base = configuration->property(role + ".device_base", 27);
trk_param_fpga.device_base = device_base; trk_param_fpga.device_base = device_base;
//unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 1);
trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> up to 5+1 correlators trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> up to 5+1 correlators
//################# PRE-COMPUTE ALL THE CODES ################# //################# PRE-COMPUTE ALL THE CODES #################
unsigned int code_samples_per_chip = 1; uint32_t code_samples_per_chip = 1;
auto code_length_chips = static_cast<unsigned int>(GALILEO_E5A_CODE_LENGTH_CHIPS); auto code_length_chips = static_cast<uint32_t>(GALILEO_E5A_CODE_LENGTH_CHIPS);
auto *aux_code = static_cast<gr_complex *>(volk_gnsssdr_malloc(sizeof(gr_complex) * code_length_chips * code_samples_per_chip, volk_gnsssdr_get_alignment())); auto *aux_code = static_cast<gr_complex *>(volk_gnsssdr_malloc(sizeof(gr_complex) * code_length_chips * code_samples_per_chip, volk_gnsssdr_get_alignment()));
float *tracking_code; d_ca_codes = static_cast<int32_t *>(volk_gnsssdr_malloc(static_cast<int32_t>(code_length_chips) * code_samples_per_chip * GALILEO_E5A_NUMBER_OF_CODES * sizeof(int32_t), volk_gnsssdr_get_alignment()));
float *data_code;
if (trk_param_fpga.track_pilot) if (trk_param_fpga.track_pilot)
{ {
data_code = static_cast<float *>(volk_gnsssdr_malloc(code_samples_per_chip * code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); d_data_codes = static_cast<int32_t *>(volk_gnsssdr_malloc((static_cast<uint32_t>(code_length_chips)) * code_samples_per_chip * GALILEO_E5A_NUMBER_OF_CODES * sizeof(int32_t), volk_gnsssdr_get_alignment()));
}
tracking_code = static_cast<float *>(volk_gnsssdr_malloc(code_samples_per_chip * code_length_chips * sizeof(float), volk_gnsssdr_get_alignment()));
d_ca_codes = static_cast<int *>(volk_gnsssdr_malloc(static_cast<int>(code_length_chips) * code_samples_per_chip * GALILEO_E5A_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment()));
if (trk_param_fpga.track_pilot)
{
d_data_codes = static_cast<int *>(volk_gnsssdr_malloc((static_cast<unsigned int>(code_length_chips)) * code_samples_per_chip * GALILEO_E5A_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment()));
} }
for (unsigned int PRN = 1; PRN <= GALILEO_E5A_NUMBER_OF_CODES; PRN++) for (uint32_t PRN = 1; PRN <= GALILEO_E5A_NUMBER_OF_CODES; PRN++)
{ {
//galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast<char *>(trk_param_fpga.signal.c_str()));
galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast<char *>(sig_)); galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast<char *>(sig_));
if (trk_param_fpga.track_pilot) if (trk_param_fpga.track_pilot)
{ {
//d_secondary_code_string = const_cast<std::string *>(&Galileo_E5a_Q_SECONDARY_CODE[PRN - 1]); for (uint32_t s = 0; s < code_length_chips; s++)
for (unsigned int i = 0; i < code_length_chips; i++)
{ {
tracking_code[i] = aux_code[i].imag(); d_ca_codes[static_cast<int32_t>(code_length_chips) * (PRN - 1) + s] = static_cast<int32_t>(aux_code[s].imag());
data_code[i] = aux_code[i].real(); d_data_codes[static_cast<int32_t>(code_length_chips) * (PRN - 1) + s] = static_cast<int32_t>(aux_code[s].real());
}
for (unsigned int s = 0; s < code_length_chips; s++)
{
d_ca_codes[static_cast<int>(code_length_chips) * (PRN - 1) + s] = static_cast<int>(tracking_code[s]);
d_data_codes[static_cast<int>(code_length_chips) * (PRN - 1) + s] = static_cast<int>(data_code[s]);
//printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]);
} }
} }
else else
{ {
for (unsigned int i = 0; i < code_length_chips; i++) for (uint32_t s = 0; s < code_length_chips; s++)
{ {
tracking_code[i] = aux_code[i].real(); d_ca_codes[static_cast<int32_t>(code_length_chips) * (PRN - 1) + s] = static_cast<int32_t>(aux_code[s].real());
}
for (unsigned int s = 0; s < code_length_chips; s++)
{
d_ca_codes[static_cast<int>(code_length_chips) * (PRN - 1) + s] = static_cast<int>(tracking_code[s]);
//printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]);
} }
} }
} }
volk_gnsssdr_free(aux_code); volk_gnsssdr_free(aux_code);
volk_gnsssdr_free(tracking_code);
if (trk_param_fpga.track_pilot)
{
volk_gnsssdr_free(data_code);
}
trk_param_fpga.ca_codes = d_ca_codes; trk_param_fpga.ca_codes = d_ca_codes;
trk_param_fpga.data_codes = d_data_codes; trk_param_fpga.data_codes = d_data_codes;
trk_param_fpga.code_length_chips = code_length_chips; trk_param_fpga.code_length_chips = code_length_chips;
trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip
//################# MAKE TRACKING GNURadio object ################### //################# MAKE TRACKING GNURadio object ###################
tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga);
// if (item_type.compare("gr_complex") == 0)
// {
// item_size_ = sizeof(gr_complex);
// tracking_ = dll_pll_veml_make_tracking(trk_param_fpga);
// }
// else
// {
// item_size_ = sizeof(gr_complex);
// LOG(WARNING) << item_type << " unknown tracking item type.";
// }
channel_ = 0; channel_ = 0;
//DLOG(INFO) << "tracking(" << tracking_->unique_id() << ")";
DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")";
} }
@ -232,7 +190,6 @@ GalileoE5aDllPllTrackingFpga::~GalileoE5aDllPllTrackingFpga()
void GalileoE5aDllPllTrackingFpga::start_tracking() void GalileoE5aDllPllTrackingFpga::start_tracking()
{ {
//tracking_->start_tracking();
tracking_fpga_sc->start_tracking(); tracking_fpga_sc->start_tracking();
} }
@ -242,16 +199,13 @@ void GalileoE5aDllPllTrackingFpga::start_tracking()
*/ */
void GalileoE5aDllPllTrackingFpga::set_channel(unsigned int channel) void GalileoE5aDllPllTrackingFpga::set_channel(unsigned int channel)
{ {
//printf("blabla channel = %d\n", channel);
channel_ = channel; channel_ = channel;
//tracking_->set_channel(channel);
tracking_fpga_sc->set_channel(channel); tracking_fpga_sc->set_channel(channel);
} }
void GalileoE5aDllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) void GalileoE5aDllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro)
{ {
//tracking_->set_gnss_synchro(p_gnss_synchro);
tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro);
} }
@ -276,13 +230,11 @@ void GalileoE5aDllPllTrackingFpga::disconnect(gr::top_block_sptr top_block)
gr::basic_block_sptr GalileoE5aDllPllTrackingFpga::get_left_block() gr::basic_block_sptr GalileoE5aDllPllTrackingFpga::get_left_block()
{ {
//return tracking_;
return tracking_fpga_sc; return tracking_fpga_sc;
} }
gr::basic_block_sptr GalileoE5aDllPllTrackingFpga::get_right_block() gr::basic_block_sptr GalileoE5aDllPllTrackingFpga::get_right_block()
{ {
//return tracking_;
return tracking_fpga_sc; return tracking_fpga_sc;
} }

View File

@ -1,19 +1,20 @@
/*! /*!
* \file galileo_e5a_dll_pll_tracking.h * \file galileo_e5a_dll_pll_tracking_fpga.h
* \brief Adapts a code DLL + carrier PLL * \brief Adapts a code DLL + carrier PLL
* tracking block to a TrackingInterface for Galileo E5a signals * tracking block to a TrackingInterface for Galileo E5a signals for the FPGA
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
* Galileo E5a data and pilot Signals * Galileo E5a data and pilot Signals for the FPGA
* \author Marc Sales, 2014. marcsales92(at)gmail.com * \author Marc Sales, 2014. marcsales92(at)gmail.com
* \based on work from: * \based on work from:
* <ul> * <ul>
* <li> Marc Majoral, 2019. mmajoral(at)cttc.cat
* <li> Javier Arribas, 2011. jarribas(at)cttc.es * <li> Javier Arribas, 2011. jarribas(at)cttc.es
* <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com * <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
* </ul> * </ul>
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -63,10 +64,10 @@ public:
return role_; return role_;
} }
//! Returns "Galileo_E5a_DLL_PLL_Tracking" //! Returns "Galileo_E5a_DLL_PLL_Tracking_Fpga"
inline std::string implementation() override inline std::string implementation() override
{ {
return "Galileo_E5a_DLL_PLL_Tracking"; return "Galileo_E5a_DLL_PLL_Tracking_Fpga";
} }
inline size_t item_size() override inline size_t item_size() override
@ -99,14 +100,14 @@ public:
private: private:
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
size_t item_size_; size_t item_size_;
unsigned int channel_; uint32_t channel_;
std::string role_; std::string role_;
unsigned int in_streams_; uint32_t in_streams_;
unsigned int out_streams_; uint32_t out_streams_;
int* d_ca_codes; int32_t* d_ca_codes;
int* d_data_codes; int32_t* d_data_codes;
bool d_track_pilot; bool d_track_pilot;
}; };

View File

@ -1,8 +1,8 @@
/*! /*!
* \file gps_l1_ca_dll_pll_tracking_fpga.cc * \file gps_l1_ca_dll_pll_tracking_fpga.cc
* \brief Implementation of an adapter of a DLL+PLL tracking loop block * \brief Implementation of an adapter of a DLL+PLL tracking loop block
* for GPS L1 C/A to a TrackingInterface that uses the FPGA * for GPS L1 C/A to a TrackingInterface for the FPGA
* \author Marc Majoral, 2018, mmajoral(at)cttc.es * \author Marc Majoral, 2019, mmajoral(at)cttc.es
* Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com * Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
* Javier Arribas, 2011. jarribas(at)cttc.es * Javier Arribas, 2011. jarribas(at)cttc.es
* *
@ -13,7 +13,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -60,10 +60,8 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
DLOG(INFO) << "role " << role; DLOG(INFO) << "role " << role;
//################# CONFIGURATION PARAMETERS ######################## //################# CONFIGURATION PARAMETERS ########################
//std::string default_item_type = "gr_complex"; int32_t fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
//std::string item_type = configuration->property(role + ".item_type", default_item_type); int32_t fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
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; trk_param_fpga.fs_in = fs_in;
bool dump = configuration->property(role + ".dump", false); bool dump = configuration->property(role + ".dump", false);
trk_param_fpga.dump = dump; trk_param_fpga.dump = dump;
@ -86,9 +84,9 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
trk_param_fpga.early_late_space_chips = early_late_space_chips; 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); 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; trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips;
int vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); int32_t 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; trk_param_fpga.vector_length = vector_length;
int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); int32_t symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1);
if (symbols_extended_correlator < 1) if (symbols_extended_correlator < 1)
{ {
symbols_extended_correlator = 1; symbols_extended_correlator = 1;
@ -115,13 +113,13 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
trk_param_fpga.system = 'G'; trk_param_fpga.system = 'G';
char sig_[3] = "1C"; char sig_[3] = "1C";
std::memcpy(trk_param_fpga.signal, sig_, 3); std::memcpy(trk_param_fpga.signal, sig_, 3);
int cn0_samples = configuration->property(role + ".cn0_samples", 20); int32_t cn0_samples = configuration->property(role + ".cn0_samples", 20);
if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples;
trk_param_fpga.cn0_samples = cn0_samples; trk_param_fpga.cn0_samples = cn0_samples;
int cn0_min = configuration->property(role + ".cn0_min", 25); int32_t cn0_min = configuration->property(role + ".cn0_min", 25);
if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min;
trk_param_fpga.cn0_min = cn0_min; trk_param_fpga.cn0_min = cn0_min;
int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); int32_t max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail;
trk_param_fpga.max_lock_fail = max_lock_fail; trk_param_fpga.max_lock_fail = max_lock_fail;
double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85);
@ -132,16 +130,15 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
std::string default_device_name = "/dev/uio"; std::string default_device_name = "/dev/uio";
std::string device_name = configuration->property(role + ".devicename", default_device_name); std::string device_name = configuration->property(role + ".devicename", default_device_name);
trk_param_fpga.device_name = device_name; trk_param_fpga.device_name = device_name;
unsigned int device_base = configuration->property(role + ".device_base", 1); uint32_t device_base = configuration->property(role + ".device_base", 3);
trk_param_fpga.device_base = device_base; trk_param_fpga.device_base = device_base;
//unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0);
trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators
//################# PRE-COMPUTE ALL THE CODES ################# //################# 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())); d_ca_codes = static_cast<int32_t*>(volk_gnsssdr_malloc(static_cast<int32_t>(GPS_L1_CA_CODE_LENGTH_CHIPS * NUM_PRNs) * sizeof(int32_t), volk_gnsssdr_get_alignment()));
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) for (uint32_t 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); gps_l1_ca_code_gen_int(&d_ca_codes[(int32_t(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0);
} }
trk_param_fpga.ca_codes = d_ca_codes; trk_param_fpga.ca_codes = d_ca_codes;
trk_param_fpga.code_length_chips = GPS_L1_CA_CODE_LENGTH_CHIPS; trk_param_fpga.code_length_chips = GPS_L1_CA_CODE_LENGTH_CHIPS;

View File

@ -1,8 +1,8 @@
/*! /*!
* \file gps_l1_ca_dll_pll_tracking_fpga.h * \file gps_l1_ca_dll_pll_tracking_fpga.h
* \brief Interface of an adapter of a DLL+PLL tracking loop block * \brief Interface of an adapter of a DLL+PLL tracking loop block
* for GPS L1 C/A to a TrackingInterface that uses the FPGA * for GPS L1 C/A to a TrackingInterface for the FPGA
* \author Marc Majoral, 2018. mmajoral(at)cttc.es * \author Marc Majoral, 2019, mmajoral(at)cttc.es
* Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com * Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
* Javier Arribas, 2011. jarribas(at)cttc.es * Javier Arribas, 2011. jarribas(at)cttc.es
* *
@ -13,7 +13,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -101,11 +101,11 @@ public:
private: private:
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
size_t item_size_; size_t item_size_;
unsigned int channel_; uint32_t channel_;
std::string role_; std::string role_;
unsigned int in_streams_; uint32_t in_streams_;
unsigned int out_streams_; uint32_t out_streams_;
int* d_ca_codes; int32_t* d_ca_codes;
}; };
#endif // GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_H_ #endif // GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_H_

View File

@ -63,7 +63,7 @@ public:
return role_; return role_;
} }
//! Returns "GPS_L2_M_DLL_PLL_Tracking" //! Returns "GPS_L2_M_DLL_PLL_Tracking_Fpga"
inline std::string implementation() override inline std::string implementation() override
{ {
return "GPS_L2_M_DLL_PLL_Tracking_Fpga"; return "GPS_L2_M_DLL_PLL_Tracking_Fpga";

View File

@ -2,6 +2,7 @@
* \file gps_l5_dll_pll_tracking.cc * \file gps_l5_dll_pll_tracking.cc
* \brief Interface of an adapter of a DLL+PLL tracking loop block * \brief Interface of an adapter of a DLL+PLL tracking loop block
* for GPS L5 to a TrackingInterface * for GPS L5 to a TrackingInterface
* \author Marc Majoral, 2019. mmajoral(at)cttc.cat
* \author Javier Arribas, 2017. jarribas(at)cttc.es * \author Javier Arribas, 2017. jarribas(at)cttc.es
* *
* Code DLL + carrier PLL according to the algorithms described in: * Code DLL + carrier PLL according to the algorithms described in:
@ -11,7 +12,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -55,15 +56,11 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga(
ConfigurationInterface *configuration, const std::string &role, ConfigurationInterface *configuration, const std::string &role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{ {
//printf("L5 TRK CLASS CREATED\n");
//dllpllconf_t trk_param;
Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga();
DLOG(INFO) << "role " << role; DLOG(INFO) << "role " << role;
//################# CONFIGURATION PARAMETERS ######################## //################# CONFIGURATION PARAMETERS ########################
//std::string default_item_type = "gr_complex"; int32_t fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 12500000);
//std::string item_type = configuration->property(role + ".item_type", default_item_type); int32_t fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
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; trk_param_fpga.fs_in = fs_in;
bool dump = configuration->property(role + ".dump", false); bool dump = configuration->property(role + ".dump", false);
trk_param_fpga.dump = dump; trk_param_fpga.dump = dump;
@ -84,9 +81,9 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga(
trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz; trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz;
float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); 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; trk_param_fpga.early_late_space_chips = early_late_space_chips;
int vector_length = std::round(static_cast<double>(fs_in) / (static_cast<double>(GPS_L5I_CODE_RATE_HZ) / static_cast<double>(GPS_L5I_CODE_LENGTH_CHIPS))); int32_t vector_length = std::round(static_cast<double>(fs_in) / (static_cast<double>(GPS_L5I_CODE_RATE_HZ) / static_cast<double>(GPS_L5I_CODE_LENGTH_CHIPS)));
trk_param_fpga.vector_length = vector_length; trk_param_fpga.vector_length = vector_length;
int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); int32_t extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1);
float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15); 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; trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips;
bool track_pilot = configuration->property(role + ".track_pilot", false); bool track_pilot = configuration->property(role + ".track_pilot", false);
@ -112,32 +109,30 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga(
trk_param_fpga.system = 'G'; trk_param_fpga.system = 'G';
char sig_[3] = "L5"; char sig_[3] = "L5";
std::memcpy(trk_param_fpga.signal, sig_, 3); std::memcpy(trk_param_fpga.signal, sig_, 3);
int cn0_samples = configuration->property(role + ".cn0_samples", 20); int32_t cn0_samples = configuration->property(role + ".cn0_samples", 20);
if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples;
trk_param_fpga.cn0_samples = cn0_samples; trk_param_fpga.cn0_samples = cn0_samples;
int cn0_min = configuration->property(role + ".cn0_min", 25); int32_t cn0_min = configuration->property(role + ".cn0_min", 25);
if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min;
trk_param_fpga.cn0_min = cn0_min; trk_param_fpga.cn0_min = cn0_min;
int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); int32_t max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail;
trk_param_fpga.max_lock_fail = max_lock_fail; trk_param_fpga.max_lock_fail = max_lock_fail;
double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.75);
if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th;
trk_param_fpga.carrier_lock_th = carrier_lock_th; trk_param_fpga.carrier_lock_th = carrier_lock_th;
// FPGA configuration parameters // FPGA configuration parameters
std::string default_device_name = "/dev/uio"; std::string default_device_name = "/dev/uio";
std::string device_name = configuration->property(role + ".devicename", default_device_name); std::string device_name = configuration->property(role + ".devicename", default_device_name);
trk_param_fpga.device_name = device_name; trk_param_fpga.device_name = device_name;
unsigned int device_base = configuration->property(role + ".device_base", 1); uint32_t device_base = configuration->property(role + ".device_base", 27);
trk_param_fpga.device_base = device_base; trk_param_fpga.device_base = device_base;
//unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0);
trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators
//################# PRE-COMPUTE ALL THE CODES ################# //################# PRE-COMPUTE ALL THE CODES #################
unsigned int code_samples_per_chip = 1; uint32_t code_samples_per_chip = 1;
auto code_length_chips = static_cast<unsigned int>(GPS_L5I_CODE_LENGTH_CHIPS); auto code_length_chips = static_cast<uint32_t>(GPS_L5I_CODE_LENGTH_CHIPS);
//printf("TRK code_length_chips = %d\n", code_length_chips);
float *tracking_code; float *tracking_code;
float *data_code; float *data_code;
@ -149,42 +144,37 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga(
data_code = static_cast<float *>(volk_gnsssdr_malloc(code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); data_code = static_cast<float *>(volk_gnsssdr_malloc(code_length_chips * sizeof(float), volk_gnsssdr_get_alignment()));
} }
d_ca_codes = static_cast<int *>(volk_gnsssdr_malloc(static_cast<int>(code_length_chips * NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); d_ca_codes = static_cast<int32_t *>(volk_gnsssdr_malloc(static_cast<int32_t>(code_length_chips * NUM_PRNs) * sizeof(int32_t), volk_gnsssdr_get_alignment()));
if (trk_param_fpga.track_pilot) if (trk_param_fpga.track_pilot)
{ {
d_data_codes = static_cast<int *>(volk_gnsssdr_malloc((static_cast<unsigned int>(code_length_chips)) * NUM_PRNs * sizeof(int), volk_gnsssdr_get_alignment())); d_data_codes = static_cast<int32_t *>(volk_gnsssdr_malloc((static_cast<uint32_t>(code_length_chips)) * NUM_PRNs * sizeof(int32_t), volk_gnsssdr_get_alignment()));
} }
//printf("start \n"); for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++)
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
{ {
if (track_pilot) if (trk_param_fpga.track_pilot)
{ {
gps_l5q_code_gen_float(tracking_code, PRN); gps_l5q_code_gen_float(tracking_code, PRN);
gps_l5i_code_gen_float(data_code, PRN); gps_l5i_code_gen_float(data_code, PRN);
for (unsigned int s = 0; s < code_length_chips; s++) for (uint32_t s = 0; s < code_length_chips; s++)
{ {
d_ca_codes[static_cast<int>(code_length_chips) * (PRN - 1) + s] = static_cast<int>(tracking_code[s]); d_ca_codes[static_cast<int32_t>(code_length_chips) * (PRN - 1) + s] = static_cast<int32_t>(tracking_code[s]);
d_data_codes[static_cast<int>(code_length_chips) * (PRN - 1) + s] = static_cast<int>(data_code[s]); d_data_codes[static_cast<int32_t>(code_length_chips) * (PRN - 1) + s] = static_cast<int32_t>(data_code[s]);
//printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]);
} }
} }
else else
{ {
gps_l5i_code_gen_float(tracking_code, PRN); gps_l5i_code_gen_float(tracking_code, PRN);
for (unsigned int s = 0; s < code_length_chips; s++) for (uint32_t s = 0; s < code_length_chips; s++)
{ {
d_ca_codes[static_cast<int>(code_length_chips) * (PRN - 1) + s] = static_cast<int>(data_code[s]); d_ca_codes[static_cast<int32_t>(code_length_chips) * (PRN - 1) + s] = static_cast<int32_t>(tracking_code[s]);
//printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]);
} }
} }
} }
//printf("end \n");
delete[] tracking_code; delete[] tracking_code;
if (trk_param_fpga.track_pilot) if (trk_param_fpga.track_pilot)
@ -195,20 +185,7 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga(
trk_param_fpga.data_codes = d_data_codes; trk_param_fpga.data_codes = d_data_codes;
trk_param_fpga.code_length_chips = code_length_chips; trk_param_fpga.code_length_chips = code_length_chips;
trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip
//################# MAKE TRACKING GNURadio object ###################
// if (item_type.compare("gr_complex") == 0)
// {
// item_size_ = sizeof(gr_complex);
// tracking_ = dll_pll_veml_make_tracking(trk_param_fpga);
// }
// else
// {
// item_size_ = sizeof(gr_complex);
// LOG(WARNING) << item_type << " unknown tracking item type.";
// }
//printf("call \n");
tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga);
//printf("end2 \n");
channel_ = 0; channel_ = 0;
DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")";
} }

View File

@ -2,6 +2,7 @@
* \file gps_l5_dll_pll_tracking.h * \file gps_l5_dll_pll_tracking.h
* \brief Interface of an adapter of a DLL+PLL tracking loop block * \brief Interface of an adapter of a DLL+PLL tracking loop block
* for GPS L5 to a TrackingInterface * for GPS L5 to a TrackingInterface
* \author Marc Majoral, 2019. mmajoral(at)cttc.cat
* \author Javier Arribas, 2017. jarribas(at)cttc.es * \author Javier Arribas, 2017. jarribas(at)cttc.es
* *
* Code DLL + carrier PLL according to the algorithms described in: * Code DLL + carrier PLL according to the algorithms described in:
@ -11,7 +12,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -95,16 +96,15 @@ public:
void stop_tracking() override; void stop_tracking() override;
private: private:
//dll_pll_veml_tracking_sptr tracking_;
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
size_t item_size_; size_t item_size_;
unsigned int channel_; uint32_t channel_;
std::string role_; std::string role_;
unsigned int in_streams_; uint32_t in_streams_;
unsigned int out_streams_; uint32_t out_streams_;
bool d_track_pilot; bool d_track_pilot;
int* d_ca_codes; int32_t* d_ca_codes;
int* d_data_codes; int32_t* d_data_codes;
}; };
#endif // GNSS_SDR_GPS_L5_DLL_PLL_TRACKING_FPGA_H_ #endif // GNSS_SDR_GPS_L5_DLL_PLL_TRACKING_FPGA_H_

View File

@ -153,7 +153,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
n++; n++;
} }
} }
d_symbol_history.resize(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); // Change fixed buffer size d_symbol_history.set_capacity(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); // Change fixed buffer size
d_symbol_history.clear(); // Clear all the elements in the buffer d_symbol_history.clear(); // Clear all the elements in the buffer
} }
else if (signal_type == "2S") else if (signal_type == "2S")
@ -405,6 +405,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
} }
// --- Initializations --- // --- Initializations ---
d_Prompt_circular_buffer.set_capacity(d_secondary_code_length);
multicorrelator_cpu.set_high_dynamics_resampler(trk_parameters.high_dyn); multicorrelator_cpu.set_high_dynamics_resampler(trk_parameters.high_dyn);
// Initial code frequency basis of NCO // Initial code frequency basis of NCO
d_code_freq_chips = d_code_chip_rate; d_code_freq_chips = d_code_chip_rate;
@ -446,13 +447,13 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
clear_tracking_vars(); clear_tracking_vars();
if (trk_parameters.smoother_length > 0) if (trk_parameters.smoother_length > 0)
{ {
d_carr_ph_history.resize(trk_parameters.smoother_length * 2); d_carr_ph_history.set_capacity(trk_parameters.smoother_length * 2);
d_code_ph_history.resize(trk_parameters.smoother_length * 2); d_code_ph_history.set_capacity(trk_parameters.smoother_length * 2);
} }
else else
{ {
d_carr_ph_history.resize(1); d_carr_ph_history.set_capacity(1);
d_code_ph_history.resize(1); d_code_ph_history.set_capacity(1);
} }
d_dump = trk_parameters.dump; d_dump = trk_parameters.dump;
@ -607,7 +608,7 @@ void dll_pll_veml_tracking::start_tracking()
n++; n++;
} }
} }
d_symbol_history.resize(22); // Change fixed buffer size d_symbol_history.set_capacity(22); // Change fixed buffer size
d_symbol_history.clear(); d_symbol_history.clear();
} }
} }
@ -649,7 +650,7 @@ void dll_pll_veml_tracking::start_tracking()
// enable tracking pull-in // enable tracking pull-in
d_state = 1; d_state = 1;
d_cloop = true; d_cloop = true;
d_Prompt_buffer_deque.clear(); d_Prompt_circular_buffer.clear();
d_last_prompt = gr_complex(0.0, 0.0); d_last_prompt = gr_complex(0.0, 0.0);
} }
@ -710,7 +711,7 @@ bool dll_pll_veml_tracking::acquire_secondary()
int32_t corr_value = 0; int32_t corr_value = 0;
for (uint32_t i = 0; i < d_secondary_code_length; i++) for (uint32_t i = 0; i < d_secondary_code_length; i++)
{ {
if (d_Prompt_buffer_deque.at(i).real() < 0.0) // symbols clipping if (d_Prompt_circular_buffer[i].real() < 0.0) // symbols clipping
{ {
if (d_secondary_code_string->at(i) == '0') if (d_secondary_code_string->at(i) == '0')
{ {
@ -866,7 +867,7 @@ void dll_pll_veml_tracking::clear_tracking_vars()
d_code_error_chips = 0.0; d_code_error_chips = 0.0;
d_code_error_filt_chips = 0.0; d_code_error_filt_chips = 0.0;
d_current_symbol = 0; d_current_symbol = 0;
d_Prompt_buffer_deque.clear(); d_Prompt_circular_buffer.clear();
d_last_prompt = gr_complex(0.0, 0.0); d_last_prompt = gr_complex(0.0, 0.0);
d_carrier_phase_rate_step_rad = 0.0; d_carrier_phase_rate_step_rad = 0.0;
d_code_phase_rate_step_chips = 0.0; d_code_phase_rate_step_chips = 0.0;
@ -902,9 +903,9 @@ void dll_pll_veml_tracking::update_tracking_vars()
double tmp_samples = 0.0; double tmp_samples = 0.0;
for (unsigned int k = 0; k < trk_parameters.smoother_length; k++) for (unsigned int k = 0; k < trk_parameters.smoother_length; k++)
{ {
tmp_cp1 += d_carr_ph_history.at(k).first; tmp_cp1 += d_carr_ph_history[k].first;
tmp_cp2 += d_carr_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).first; tmp_cp2 += d_carr_ph_history[trk_parameters.smoother_length * 2 - k - 1].first;
tmp_samples += d_carr_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).second; tmp_samples += d_carr_ph_history[trk_parameters.smoother_length * 2 - k - 1].second;
} }
tmp_cp1 /= static_cast<double>(trk_parameters.smoother_length); tmp_cp1 /= static_cast<double>(trk_parameters.smoother_length);
tmp_cp2 /= static_cast<double>(trk_parameters.smoother_length); tmp_cp2 /= static_cast<double>(trk_parameters.smoother_length);
@ -916,7 +917,6 @@ void dll_pll_veml_tracking::update_tracking_vars()
d_rem_carr_phase_rad += static_cast<float>(d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples) + 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples)); d_rem_carr_phase_rad += static_cast<float>(d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples) + 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples));
d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, PI_2); d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, PI_2);
// carrier phase accumulator // carrier phase accumulator
//double a = d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples); //double a = d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples);
//double b = 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples); //double b = 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples);
@ -936,9 +936,9 @@ void dll_pll_veml_tracking::update_tracking_vars()
double tmp_samples = 0.0; double tmp_samples = 0.0;
for (unsigned int k = 0; k < trk_parameters.smoother_length; k++) for (unsigned int k = 0; k < trk_parameters.smoother_length; k++)
{ {
tmp_cp1 += d_code_ph_history.at(k).first; tmp_cp1 += d_code_ph_history[k].first;
tmp_cp2 += d_code_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).first; tmp_cp2 += d_code_ph_history[trk_parameters.smoother_length * 2 - k - 1].first;
tmp_samples += d_code_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).second; tmp_samples += d_code_ph_history[trk_parameters.smoother_length * 2 - k - 1].second;
} }
tmp_cp1 /= static_cast<double>(trk_parameters.smoother_length); tmp_cp1 /= static_cast<double>(trk_parameters.smoother_length);
tmp_cp2 /= static_cast<double>(trk_parameters.smoother_length); tmp_cp2 /= static_cast<double>(trk_parameters.smoother_length);
@ -1503,8 +1503,8 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
if (d_secondary) if (d_secondary)
{ {
// ####### SECONDARY CODE LOCK ##### // ####### SECONDARY CODE LOCK #####
d_Prompt_buffer_deque.push_back(*d_Prompt); d_Prompt_circular_buffer.push_back(*d_Prompt);
if (d_Prompt_buffer_deque.size() == d_secondary_code_length) if (d_Prompt_circular_buffer.size() == d_secondary_code_length)
{ {
next_state = acquire_secondary(); next_state = acquire_secondary();
if (next_state) if (next_state)
@ -1514,8 +1514,6 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
std::cout << systemName << " " << signal_pretty_name << " secondary code locked in channel " << d_channel std::cout << systemName << " " << signal_pretty_name << " secondary code locked in channel " << d_channel
<< " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl;
} }
d_Prompt_buffer_deque.pop_front();
} }
} }
else if (d_symbols_per_bit > 1) //Signal does not have secondary code. Search a bit transition by sign change else if (d_symbols_per_bit > 1) //Signal does not have secondary code. Search a bit transition by sign change
@ -1528,9 +1526,10 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
int32_t corr_value = 0; int32_t corr_value = 0;
if ((static_cast<int32_t>(d_symbol_history.size()) == d_preamble_length_symbols)) // and (d_make_correlation or !d_flag_frame_sync)) if ((static_cast<int32_t>(d_symbol_history.size()) == d_preamble_length_symbols)) // and (d_make_correlation or !d_flag_frame_sync))
{ {
for (int32_t i = 0; i < d_preamble_length_symbols; i++) int i = 0;
for (const auto &iter : d_symbol_history)
{ {
if (d_symbol_history.at(i) < 0) // symbols clipping if (iter < 0.0) // symbols clipping
{ {
corr_value -= d_preambles_symbols[i]; corr_value -= d_preambles_symbols[i];
} }
@ -1538,6 +1537,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
{ {
corr_value += d_preambles_symbols[i]; corr_value += d_preambles_symbols[i];
} }
i++;
} }
} }
if (corr_value == d_preamble_length_symbols) if (corr_value == d_preamble_length_symbols)
@ -1606,7 +1606,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
d_L_accu = gr_complex(0.0, 0.0); d_L_accu = gr_complex(0.0, 0.0);
d_VL_accu = gr_complex(0.0, 0.0); d_VL_accu = gr_complex(0.0, 0.0);
d_last_prompt = gr_complex(0.0, 0.0); d_last_prompt = gr_complex(0.0, 0.0);
d_Prompt_buffer_deque.clear(); d_Prompt_circular_buffer.clear();
d_current_symbol = 0; d_current_symbol = 0;
if (d_enable_extended_integration) if (d_enable_extended_integration)

View File

@ -113,6 +113,7 @@ private:
// tracking state machine // tracking state machine
int32_t d_state; int32_t d_state;
// Integration period in samples // Integration period in samples
int32_t d_correlation_length_ms; int32_t d_correlation_length_ms;
int32_t d_n_correlator_taps; int32_t d_n_correlator_taps;
@ -188,11 +189,10 @@ private:
// CN0 estimation and lock detector // CN0 estimation and lock detector
int32_t d_cn0_estimation_counter; int32_t d_cn0_estimation_counter;
int32_t d_carrier_lock_fail_counter; int32_t d_carrier_lock_fail_counter;
std::deque<float> d_carrier_lock_detector_queue;
double d_carrier_lock_test; double d_carrier_lock_test;
double d_CN0_SNV_dB_Hz; double d_CN0_SNV_dB_Hz;
double d_carrier_lock_threshold; double d_carrier_lock_threshold;
std::deque<gr_complex> d_Prompt_buffer_deque; boost::circular_buffer<gr_complex> d_Prompt_circular_buffer;
gr_complex *d_Prompt_buffer; gr_complex *d_Prompt_buffer;
// file dump // file dump

View File

@ -1,19 +1,13 @@
/*! /*!
* \file gps_l1_ca_dll_pll_tracking_fpga.h * \file dll_pll_veml_tracking_fpga.h
* \brief Interface of a code DLL + carrier PLL tracking block * \brief Implementation of a code DLL + carrier PLL tracking block using an FPGA.
* \author Marc Majoral, 2018. marc.majoral(at)cttc.es * \author Marc Majoral, 2019. marc.majoral(at)cttc.es
* Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com * \author Javier Arribas, 2018. jarribas(at)cttc.es
* Javier Arribas, 2011. jarribas(at)cttc.es * \author Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com
* Cillian O'Driscoll, 2017. cillian.odriscoll(at)gmail.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) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -31,7 +25,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
@ -49,18 +43,18 @@
#include <fstream> #include <fstream>
#include <map> #include <map>
#include <queue> #include <queue>
#include <string> #include <utility>
//#include <string>
class dll_pll_veml_tracking_fpga; class dll_pll_veml_tracking_fpga;
typedef boost::shared_ptr<dll_pll_veml_tracking_fpga> using dll_pll_veml_tracking_fpga_sptr = boost::shared_ptr<dll_pll_veml_tracking_fpga>;
dll_pll_veml_tracking_fpga_sptr;
dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_); dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_);
/*! /*!
* \brief This class implements a DLL + PLL tracking loop block * \brief This class implements a code DLL + carrier PLL tracking block.
*/ */
class dll_pll_veml_tracking_fpga : public gr::block class dll_pll_veml_tracking_fpga : public gr::block
{ {
@ -71,6 +65,7 @@ public:
void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro); void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro);
void start_tracking(); void start_tracking();
void stop_tracking(); void stop_tracking();
int general_work(int noutput_items, gr_vector_int &ninput_items, int general_work(int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
@ -84,6 +79,7 @@ private:
bool cn0_and_tracking_lock_status(double coh_integration_time_s); bool cn0_and_tracking_lock_status(double coh_integration_time_s);
bool acquire_secondary(); bool acquire_secondary();
void do_correlation_step(void);
void run_dll_pll(); void run_dll_pll();
void update_tracking_vars(); void update_tracking_vars();
void clear_tracking_vars(); void clear_tracking_vars();
@ -91,9 +87,10 @@ private:
void log_data(bool integrating); void log_data(bool integrating);
int32_t save_matfile(); int32_t save_matfile();
void run_state_2(Gnss_Synchro &current_synchro_data);
// tracking configuration vars // tracking configuration vars
Dll_Pll_Conf_Fpga trk_parameters; Dll_Pll_Conf_Fpga trk_parameters;
//dllpllconf_fpga_t trk_parameters;
bool d_veml; bool d_veml;
bool d_cloop; bool d_cloop;
uint32_t d_channel; uint32_t d_channel;
@ -119,14 +116,20 @@ private:
//tracking state machine //tracking state machine
int32_t d_state; int32_t d_state;
bool d_synchonizing;
//Integration period in samples //Integration period in samples
int32_t d_correlation_length_ms; int32_t d_correlation_length_ms;
int32_t d_n_correlator_taps; int32_t d_n_correlator_taps;
float *d_tracking_code;
float *d_data_code;
float *d_local_code_shift_chips; float *d_local_code_shift_chips;
float *d_prompt_data_shift; float *d_prompt_data_shift;
std::shared_ptr<fpga_multicorrelator_8sc> multicorrelator_fpga; std::shared_ptr<Fpga_Multicorrelator_8sc> multicorrelator_fpga;
/* TODO: currently the multicorrelator does not support adding extra correlator
with different local code, thus we need extra multicorrelator instance.
Implement this functionality inside multicorrelator class
as an enhancement to increase the performance
*/
gr_complex *d_correlator_outs; gr_complex *d_correlator_outs;
gr_complex *d_Very_Early; gr_complex *d_Very_Early;
gr_complex *d_Early; gr_complex *d_Early;
@ -148,10 +151,14 @@ private:
gr_complex *d_Prompt_Data; gr_complex *d_Prompt_Data;
double d_code_phase_step_chips; double d_code_phase_step_chips;
double d_code_phase_rate_step_chips;
boost::circular_buffer<std::pair<double, double>> d_code_ph_history;
double d_carrier_phase_step_rad; double d_carrier_phase_step_rad;
double d_carrier_phase_rate_step_rad;
boost::circular_buffer<std::pair<double, double>> d_carr_ph_history;
// remaining code phase and carrier phase between tracking loops // remaining code phase and carrier phase between tracking loops
double d_rem_code_phase_samples; double d_rem_code_phase_samples;
double d_rem_carr_phase_rad; float d_rem_carr_phase_rad;
// PLL and DLL filter library // PLL and DLL filter library
Tracking_2nd_DLL_filter d_code_loop_filter; Tracking_2nd_DLL_filter d_code_loop_filter;
@ -166,12 +173,10 @@ private:
double d_carr_error_filt_hz; double d_carr_error_filt_hz;
double d_code_error_chips; double d_code_error_chips;
double d_code_error_filt_chips; double d_code_error_filt_chips;
double d_K_blk_samples;
double d_code_freq_chips; double d_code_freq_chips;
double d_carrier_doppler_hz; double d_carrier_doppler_hz;
double d_acc_carrier_phase_rad; double d_acc_carrier_phase_rad;
double d_rem_code_phase_chips; double d_rem_code_phase_chips;
double d_code_phase_samples;
double T_chip_seconds; double T_chip_seconds;
double T_prn_seconds; double T_prn_seconds;
double T_prn_samples; double T_prn_samples;
@ -181,11 +186,13 @@ private:
// processing samples counters // processing samples counters
uint64_t d_sample_counter; uint64_t d_sample_counter;
uint64_t d_acq_sample_stamp; uint64_t d_acq_sample_stamp;
uint64_t d_absolute_samples_offset; uint64_t d_absolute_samples_offset;
// CN0 estimation and lock detector // CN0 estimation and lock detector
int32_t d_cn0_estimation_counter; int32_t d_cn0_estimation_counter;
int32_t d_carrier_lock_fail_counter; int32_t d_carrier_lock_fail_counter;
std::deque<float> d_carrier_lock_detector_queue;
double d_carrier_lock_test; double d_carrier_lock_test;
double d_CN0_SNV_dB_Hz; double d_CN0_SNV_dB_Hz;
double d_carrier_lock_threshold; double d_carrier_lock_threshold;
@ -202,7 +209,6 @@ private:
int32_t d_correlation_length_samples; int32_t d_correlation_length_samples;
int32_t d_next_prn_length_samples; int32_t d_next_prn_length_samples;
uint64_t d_sample_counter_next; uint64_t d_sample_counter_next;
uint32_t d_pull_in = 0U;
}; };
#endif //GNSS_SDR_DLL_PLL_VEML_TRACKING_FPGA_H #endif //GNSS_SDR_DLL_PLL_VEML_TRACKING_FPGA_H

View File

@ -1,12 +1,13 @@
/*! /*!
* \file dll_pll_conf.cc * \file dll_pll_conf_fpga.cc
* \brief Class that contains all the configuration parameters for generic * \brief Class that contains all the configuration parameters for generic
* tracking block based on a DLL and a PLL. * tracking block based on a DLL and a PLL for the FPGA.
* \author Marc Majoral, 2019. mmajoral(at)cttc.cat
* \author Javier Arribas, 2018. jarribas(at)cttc.es * \author Javier Arribas, 2018. jarribas(at)cttc.es
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -36,12 +37,14 @@
Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga() Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga()
{ {
/* DLL/PLL tracking configuration */ /* DLL/PLL tracking configuration */
high_dyn = false;
smoother_length = 10;
fs_in = 0.0; fs_in = 0.0;
vector_length = 0U; vector_length = 0U;
dump = false; dump = false;
dump_mat = true; dump_mat = true;
dump_filename = std::string("./dll_pll_dump.dat"); dump_filename = std::string("./dll_pll_dump.dat");
pll_bw_hz = 40.0; pll_bw_hz = 35.0;
dll_bw_hz = 2.0; dll_bw_hz = 2.0;
pll_bw_narrow_hz = 5.0; pll_bw_narrow_hz = 5.0;
dll_bw_narrow_hz = 0.75; dll_bw_narrow_hz = 0.75;

View File

@ -1,13 +1,15 @@
/*! /*!
* \file dll_pll_conf.h * \file dll_pll_conf_fpga.h
* \brief Class that contains all the configuration parameters for generic tracking block based on a DLL and a PLL. * \brief Class that contains all the configuration parameters for generic
* tracking block based on a DLL and a PLL for the FPGA.
* \author Marc Majoral, 2019. mmajoral(at)cttc.cat
* \author Javier Arribas, 2018. jarribas(at)cttc.es * \author Javier Arribas, 2018. jarribas(at)cttc.es
* *
* Class that contains all the configuration parameters for generic tracking block based on a DLL and a PLL. * Class that contains all the configuration parameters for generic tracking block based on a DLL and a PLL.
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -54,9 +56,11 @@ public:
float early_late_space_narrow_chips; float early_late_space_narrow_chips;
float very_early_late_space_narrow_chips; float very_early_late_space_narrow_chips;
int32_t extend_correlation_symbols; int32_t extend_correlation_symbols;
bool high_dyn;
int32_t cn0_samples; int32_t cn0_samples;
int32_t cn0_min; int32_t cn0_min;
int32_t max_lock_fail; int32_t max_lock_fail;
uint32_t smoother_length;
double carrier_lock_th; double carrier_lock_th;
bool track_pilot; bool track_pilot;
char system; char system;

View File

@ -2,7 +2,7 @@
* \file fpga_multicorrelator_8sc.cc * \file fpga_multicorrelator_8sc.cc
* \brief High optimized FPGA vector correlator class * \brief High optimized FPGA vector correlator class
* \authors <ul> * \authors <ul>
* <li> Marc Majoral, 2017. mmajoral(at)cttc.cat * <li> Marc Majoral, 2019. mmajoral(at)cttc.cat
* <li> Javier Arribas, 2015. jarribas(at)cttc.es * <li> Javier Arribas, 2015. jarribas(at)cttc.es
* </ul> * </ul>
* *
@ -11,7 +11,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -35,41 +35,23 @@
*/ */
#include "fpga_multicorrelator.h" #include "fpga_multicorrelator.h"
#include <cmath> #include <glog/logging.h>
// FPGA stuff
#include <new>
// libraries used by DMA test code and GIPO test code
#include <cerrno>
#include <cstdio>
#include <fcntl.h>
#include <unistd.h>
// libraries used by DMA test code
#include <cassert> #include <cassert>
#include <cerrno>
#include <cmath>
#include <csignal>
#include <cstdint> #include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <new>
#include <string>
#include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
// libraries used by GPIO test code
#include <csignal>
#include <cstdlib>
#include <sys/mman.h>
// logging
#include <glog/logging.h>
// string manipulation
#include <string>
#include <utility> #include <utility>
// constants // FPGA register access constants
#include "GPS_L1_CA.h"
//#include "gps_sdr_signal_processing.h"
#define NUM_PRNs 32
#define PAGE_SIZE 0x10000 #define PAGE_SIZE 0x10000
#define MAX_LENGTH_DEVICEIO_NAME 50 #define MAX_LENGTH_DEVICEIO_NAME 50
#define CODE_RESAMPLER_NUM_BITS_PRECISION 20 #define CODE_RESAMPLER_NUM_BITS_PRECISION 20
@ -84,54 +66,50 @@
#define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000 #define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000
#define TEST_REGISTER_TRACK_WRITEVAL 0x55AA #define TEST_REGISTER_TRACK_WRITEVAL 0x55AA
uint64_t fpga_multicorrelator_8sc::read_sample_counter()
uint64_t Fpga_Multicorrelator_8sc::read_sample_counter()
{ {
uint64_t sample_counter_tmp, sample_counter_msw_tmp; uint64_t sample_counter_tmp, sample_counter_msw_tmp;
sample_counter_tmp = d_map_base[d_SAMPLE_COUNTER_REG_ADDR_LSW]; sample_counter_tmp = d_map_base[SAMPLE_COUNTER_REG_ADDR_LSW];
sample_counter_msw_tmp = d_map_base[d_SAMPLE_COUNTER_REG_ADDR_MSW]; sample_counter_msw_tmp = d_map_base[SAMPLE_COUNTER_REG_ADDR_MSW];
sample_counter_msw_tmp = sample_counter_msw_tmp << 32; sample_counter_msw_tmp = sample_counter_msw_tmp << 32;
sample_counter_tmp = sample_counter_tmp + sample_counter_msw_tmp; // 2^32 sample_counter_tmp = sample_counter_tmp + sample_counter_msw_tmp; // 2^32
//return d_map_base[d_SAMPLE_COUNTER_REG_ADDR];
return sample_counter_tmp; return sample_counter_tmp;
} }
void fpga_multicorrelator_8sc::set_initial_sample(uint64_t samples_offset) void Fpga_Multicorrelator_8sc::set_initial_sample(uint64_t samples_offset)
{ {
d_initial_sample_counter = samples_offset; d_initial_sample_counter = samples_offset;
//printf("www writing d map base %d = d_initial_sample_counter = %d\n", d_INITIAL_COUNTER_VALUE_REG_ADDR, d_initial_sample_counter); d_map_base[INITIAL_COUNTER_VALUE_REG_ADDR_LSW] = (d_initial_sample_counter & 0xFFFFFFFF);
d_map_base[d_INITIAL_COUNTER_VALUE_REG_ADDR_LSW] = (d_initial_sample_counter & 0xFFFFFFFF); d_map_base[INITIAL_COUNTER_VALUE_REG_ADDR_MSW] = (d_initial_sample_counter >> 32) & 0xFFFFFFFF;
d_map_base[d_INITIAL_COUNTER_VALUE_REG_ADDR_MSW] = (d_initial_sample_counter >> 32) & 0xFFFFFFFF;
} }
//void fpga_multicorrelator_8sc::set_local_code_and_taps(int32_t code_length_chips, void Fpga_Multicorrelator_8sc::set_local_code_and_taps(float *shifts_chips, float *prompt_data_shift, int32_t PRN)
// float *shifts_chips, int32_t PRN)
void fpga_multicorrelator_8sc::set_local_code_and_taps(float *shifts_chips, float *prompt_data_shift, int32_t PRN)
{ {
d_shifts_chips = shifts_chips; d_shifts_chips = shifts_chips;
d_prompt_data_shift = prompt_data_shift; d_prompt_data_shift = prompt_data_shift;
//d_code_length_chips = code_length_chips; Fpga_Multicorrelator_8sc::fpga_configure_tracking_gps_local_code(PRN);
fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(PRN);
} }
void fpga_multicorrelator_8sc::set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data) void Fpga_Multicorrelator_8sc::set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data)
{ {
d_corr_out = corr_out; d_corr_out = corr_out;
d_Prompt_Data = Prompt_Data; d_Prompt_Data = Prompt_Data;
} }
void fpga_multicorrelator_8sc::update_local_code(float rem_code_phase_chips) void Fpga_Multicorrelator_8sc::update_local_code(float rem_code_phase_chips)
{ {
d_rem_code_phase_chips = rem_code_phase_chips; d_rem_code_phase_chips = rem_code_phase_chips;
//printf("uuuuu d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips); Fpga_Multicorrelator_8sc::fpga_compute_code_shift_parameters();
fpga_multicorrelator_8sc::fpga_compute_code_shift_parameters(); Fpga_Multicorrelator_8sc::fpga_configure_code_parameters_in_fpga();
fpga_multicorrelator_8sc::fpga_configure_code_parameters_in_fpga();
} }
void fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler( void Fpga_Multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler(
float rem_carrier_phase_in_rad, float phase_step_rad, float rem_carrier_phase_in_rad, float phase_step_rad,
float carrier_phase_rate_step_rad,
float rem_code_phase_chips, float code_phase_step_chips, float rem_code_phase_chips, float code_phase_step_chips,
float code_phase_rate_step_chips,
int32_t signal_length_samples) int32_t signal_length_samples)
{ {
update_local_code(rem_code_phase_chips); update_local_code(rem_code_phase_chips);
@ -139,27 +117,24 @@ void fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler(
d_code_phase_step_chips = code_phase_step_chips; d_code_phase_step_chips = code_phase_step_chips;
d_phase_step_rad = phase_step_rad; d_phase_step_rad = phase_step_rad;
d_correlator_length_samples = signal_length_samples; d_correlator_length_samples = signal_length_samples;
fpga_multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(); Fpga_Multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga();
fpga_multicorrelator_8sc::fpga_configure_signal_parameters_in_fpga(); Fpga_Multicorrelator_8sc::fpga_configure_signal_parameters_in_fpga();
fpga_multicorrelator_8sc::fpga_launch_multicorrelator_fpga(); Fpga_Multicorrelator_8sc::fpga_launch_multicorrelator_fpga();
int32_t irq_count; int32_t irq_count;
ssize_t nb; ssize_t nb;
//printf("$$$$$ waiting for interrupt ... \n");
nb = read(d_device_descriptor, &irq_count, sizeof(irq_count)); nb = read(d_device_descriptor, &irq_count, sizeof(irq_count));
//printf("$$$$$ interrupt received ... \n");
if (nb != sizeof(irq_count)) if (nb != sizeof(irq_count))
{ {
printf("Tracking_module Read failed to retrieve 4 bytes!\n"); std::cout << "Tracking_module Read failed to retrieve 4 bytes!" << std::endl;
printf("Tracking_module Interrupt number %d\n", irq_count); std::cout << "Tracking_module Interrupt number " << irq_count << std::endl;
} }
fpga_multicorrelator_8sc::read_tracking_gps_results(); Fpga_Multicorrelator_8sc::read_tracking_gps_results();
} }
fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int32_t n_correlators, Fpga_Multicorrelator_8sc::Fpga_Multicorrelator_8sc(int32_t n_correlators,
std::string device_name, uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, std::string device_name, uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot,
uint32_t multicorr_type, uint32_t code_samples_per_chip) uint32_t multicorr_type, uint32_t code_samples_per_chip)
{ {
//printf("tracking fpga class created\n");
d_n_correlators = n_correlators; d_n_correlators = n_correlators;
d_device_name = std::move(device_name); d_device_name = std::move(device_name);
d_device_base = device_base; d_device_base = device_base;
@ -195,111 +170,26 @@ fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int32_t n_correlators,
d_initial_sample_counter = 0; d_initial_sample_counter = 0;
d_channel = 0; d_channel = 0;
d_correlator_length_samples = 0, d_correlator_length_samples = 0,
//d_code_length = code_length;
d_code_length_chips = code_length_chips; d_code_length_chips = code_length_chips;
d_ca_codes = ca_codes; d_ca_codes = ca_codes;
d_data_codes = data_codes; d_data_codes = data_codes;
d_multicorr_type = multicorr_type; d_multicorr_type = multicorr_type;
d_code_samples_per_chip = code_samples_per_chip; d_code_samples_per_chip = code_samples_per_chip;
// set up register mapping
// write-only registers
d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR = 0;
d_INITIAL_INDEX_REG_BASE_ADDR = 1;
// if (d_multicorr_type == 0)
// {
// // multicorrelator with 3 correlators (16 registers only)
// d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR = 4;
// d_NSAMPLES_MINUS_1_REG_ADDR = 7;
// d_CODE_LENGTH_MINUS_1_REG_ADDR = 8;
// d_REM_CARR_PHASE_RAD_REG_ADDR = 9;
// d_PHASE_STEP_RAD_REG_ADDR = 10;
// d_PROG_MEMS_ADDR = 11;
// d_DROP_SAMPLES_REG_ADDR = 12;
// d_INITIAL_COUNTER_VALUE_REG_ADDR = 13;
// d_START_FLAG_ADDR = 14;
// }
// else
// {
// other types of multicorrelators (32 registers)
d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR = 7;
d_NSAMPLES_MINUS_1_REG_ADDR = 13;
d_CODE_LENGTH_MINUS_1_REG_ADDR = 14;
d_REM_CARR_PHASE_RAD_REG_ADDR = 15;
d_PHASE_STEP_RAD_REG_ADDR = 16;
d_PROG_MEMS_ADDR = 17;
d_DROP_SAMPLES_REG_ADDR = 18;
d_INITIAL_COUNTER_VALUE_REG_ADDR_LSW = 19;
d_INITIAL_COUNTER_VALUE_REG_ADDR_MSW = 20;
d_START_FLAG_ADDR = 30;
// }
//printf("d_n_correlators = %d\n", d_n_correlators);
//printf("d_multicorr_type = %d\n", d_multicorr_type);
// read-write registers
// if (d_multicorr_type == 0)
// {
// // multicorrelator with 3 correlators (16 registers only)
// d_TEST_REG_ADDR = 15;
// }
// else
// {
// other types of multicorrelators (32 registers)
d_TEST_REG_ADDR = 31;
// }
// result 2's complement saturation value
// if (d_multicorr_type == 0)
// {
// // multicorrelator with 3 correlators (16 registers only)
// d_result_SAT_value = 1048576; // 21 bits 2's complement -> 2^20
// }
// else
// {
// // other types of multicorrelators (32 registers)
// d_result_SAT_value = 4194304; // 23 bits 2's complement -> 2^22
// }
// read only registers
d_RESULT_REG_REAL_BASE_ADDR = 1;
// if (d_multicorr_type == 0)
// {
// // multicorrelator with 3 correlators (16 registers only)
// d_RESULT_REG_IMAG_BASE_ADDR = 4;
// d_RESULT_REG_DATA_REAL_BASE_ADDR = 0; // no pilot tracking
// d_RESULT_REG_DATA_IMAG_BASE_ADDR = 0;
// d_SAMPLE_COUNTER_REG_ADDR = 7;
//
// }
// else
// {
// other types of multicorrelators (32 registers)
d_RESULT_REG_IMAG_BASE_ADDR = 7;
d_RESULT_REG_DATA_REAL_BASE_ADDR = 6; // no pilot tracking
d_RESULT_REG_DATA_IMAG_BASE_ADDR = 12;
d_SAMPLE_COUNTER_REG_ADDR_LSW = 13;
d_SAMPLE_COUNTER_REG_ADDR_MSW = 14;
// }
//printf("d_SAMPLE_COUNTER_REG_ADDR = %d\n", d_SAMPLE_COUNTER_REG_ADDR);
//printf("mmmmmmmmmmmmm d_n_correlators = %d\n", d_n_correlators);
DLOG(INFO) << "TRACKING FPGA CLASS CREATED"; DLOG(INFO) << "TRACKING FPGA CLASS CREATED";
} }
fpga_multicorrelator_8sc::~fpga_multicorrelator_8sc() Fpga_Multicorrelator_8sc::~Fpga_Multicorrelator_8sc()
{ {
//delete[] d_ca_codes;
close_device(); close_device();
} }
bool fpga_multicorrelator_8sc::free() bool Fpga_Multicorrelator_8sc::free()
{ {
// unlock the channel // unlock the channel
fpga_multicorrelator_8sc::unlock_channel(); Fpga_Multicorrelator_8sc::unlock_channel();
// free the FPGA dynamically created variables // free the FPGA dynamically created variables
if (d_initial_index != nullptr) if (d_initial_index != nullptr)
@ -318,9 +208,8 @@ bool fpga_multicorrelator_8sc::free()
} }
void fpga_multicorrelator_8sc::set_channel(uint32_t channel) void Fpga_Multicorrelator_8sc::set_channel(uint32_t channel)
{ {
//printf("www trk set channel\n");
char device_io_name[MAX_LENGTH_DEVICEIO_NAME]; // driver io name char device_io_name[MAX_LENGTH_DEVICEIO_NAME]; // driver io name
d_channel = channel; d_channel = channel;
@ -332,20 +221,13 @@ void fpga_multicorrelator_8sc::set_channel(uint32_t channel)
mergedname = d_device_name + devicebasetemp.str(); mergedname = d_device_name + devicebasetemp.str();
strcpy(device_io_name, mergedname.c_str()); strcpy(device_io_name, mergedname.c_str());
//printf("ppps opening device %s\n", device_io_name); std::cout << "trk device_io_name = " << device_io_name << std::endl;
if ((d_device_descriptor = open(device_io_name, O_RDWR | O_SYNC)) == -1) if ((d_device_descriptor = open(device_io_name, O_RDWR | O_SYNC)) == -1)
{ {
LOG(WARNING) << "Cannot open deviceio" << device_io_name; LOG(WARNING) << "Cannot open deviceio" << device_io_name;
std::cout << "Cannot open deviceio" << device_io_name << std::endl; std::cout << "Cannot open deviceio" << device_io_name << std::endl;
//printf("error opening device\n");
} }
// else
// {
// std::cout << "deviceio" << device_io_name << " opened successfully" << std::endl;
//
// }
d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, PAGE_SIZE, d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0)); PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0));
@ -354,79 +236,47 @@ void fpga_multicorrelator_8sc::set_channel(uint32_t channel)
LOG(WARNING) << "Cannot map the FPGA tracking module " LOG(WARNING) << "Cannot map the FPGA tracking module "
<< d_channel << "into user memory"; << d_channel << "into user memory";
std::cout << "Cannot map deviceio" << device_io_name << std::endl; std::cout << "Cannot map deviceio" << device_io_name << std::endl;
//printf("error mapping registers\n");
} }
// else
// {
// std::cout << "deviceio" << device_io_name << "mapped successfully" << std::endl;
// }
// else
// {
// printf("trk mapping registers succes\n"); // this is for debug -- remove !
// }
// sanity check : check test register // sanity check : check test register
uint32_t writeval = TEST_REGISTER_TRACK_WRITEVAL; uint32_t writeval = TEST_REGISTER_TRACK_WRITEVAL;
uint32_t readval; uint32_t readval;
readval = fpga_multicorrelator_8sc::fpga_acquisition_test_register(writeval); readval = Fpga_Multicorrelator_8sc::fpga_acquisition_test_register(writeval);
if (writeval != readval) if (writeval != readval)
{ {
LOG(WARNING) << "Test register sanity check failed"; LOG(WARNING) << "Test register sanity check failed";
printf("tracking test register sanity check failed\n"); std::cout << "tracking test register sanity check failed" << std::endl;
//printf("lslslls test sanity check reg failure\n");
} }
else else
{ {
LOG(INFO) << "Test register sanity check success !"; LOG(INFO) << "Test register sanity check success !";
//printf("tracking test register sanity check success\n");
//printf("lslslls test sanity check reg success\n");
} }
} }
uint32_t fpga_multicorrelator_8sc::fpga_acquisition_test_register( uint32_t Fpga_Multicorrelator_8sc::fpga_acquisition_test_register(
uint32_t writeval) uint32_t writeval)
{ {
//printf("d_TEST_REG_ADDR = %d\n", d_TEST_REG_ADDR);
uint32_t readval = 0; uint32_t readval = 0;
// write value to test register // write value to test register
d_map_base[d_TEST_REG_ADDR] = writeval; d_map_base[TEST_REG_ADDR] = writeval;
// read value from test register // read value from test register
readval = d_map_base[d_TEST_REG_ADDR]; readval = d_map_base[TEST_REG_ADDR];
// return read value // return read value
return readval; return readval;
} }
void fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int32_t PRN) void Fpga_Multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int32_t PRN)
{ {
uint32_t k; uint32_t k;
uint32_t code_chip; uint32_t code_chip;
uint32_t select_pilot_corelator = LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT; uint32_t select_pilot_corelator = LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT;
// select_fpga_correlator = 0;
//printf("kkk d_n_correlators = %x\n", d_n_correlators); d_map_base[PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER;
//printf("kkk d_code_length_chips = %d\n", d_code_length_chips);
//printf("programming mems d map base %d\n", d_PROG_MEMS_ADDR);
//FILE *fp;
//char str[80];
//sprintf(str, "generated_code_PRN%d", PRN);
//fp = fopen(str,"w");
// for (s = 0; s < d_n_correlators; s++)
// {
//printf("kkk select_fpga_correlator = %x\n", select_fpga_correlator);
d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER;
for (k = 0; k < d_code_length_chips * d_code_samples_per_chip; k++) for (k = 0; k < d_code_length_chips * d_code_samples_per_chip; k++)
{ {
//if (d_local_code_in[k] == 1) if (d_ca_codes[((int32_t(d_code_length_chips)) * d_code_samples_per_chip * (PRN - 1)) + k] == 1)
//printf("kkk d_ca_codes %d = %d\n", k, d_ca_codes[((int(d_code_length)) * (PRN - 1)) + k]);
//fprintf(fp, "%d\n", d_ca_codes[((int(d_code_length_chips)) * d_code_samples_per_chip * (PRN - 1)) + k]);
if (d_ca_codes[((int(d_code_length_chips)) * d_code_samples_per_chip * (PRN - 1)) + k] == 1)
{ {
code_chip = 1; code_chip = 1;
} }
@ -436,22 +286,14 @@ void fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int32_t PR
} }
// copy the local code to the FPGA memory one by one // copy the local code to the FPGA memory one by one
d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY | code_chip; // | select_fpga_correlator; d_map_base[PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY | code_chip; // | select_fpga_correlator;
} }
// select_fpga_correlator = select_fpga_correlator
// + LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT;
// }
//fclose(fp);
//printf("kkk d_track_pilot = %d\n", d_track_pilot);
if (d_track_pilot) if (d_track_pilot)
{ {
//printf("kkk select_fpga_correlator = %x\n", select_fpga_correlator); d_map_base[PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER;
d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER;
for (k = 0; k < d_code_length_chips * d_code_samples_per_chip; k++) for (k = 0; k < d_code_length_chips * d_code_samples_per_chip; k++)
{ {
//if (d_local_code_in[k] == 1) if (d_data_codes[((int32_t(d_code_length_chips)) * d_code_samples_per_chip * (PRN - 1)) + k] == 1)
if (d_data_codes[((int(d_code_length_chips)) * d_code_samples_per_chip * (PRN - 1)) + k] == 1)
{ {
code_chip = 1; code_chip = 1;
} }
@ -459,53 +301,38 @@ void fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int32_t PR
{ {
code_chip = 0; code_chip = 0;
} }
//printf("%d %d | ", d_data_codes, code_chip); d_map_base[PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY | code_chip | select_pilot_corelator;
// copy the local code to the FPGA memory one by one
d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY | code_chip | select_pilot_corelator;
} }
} }
//printf("\n");
} }
void fpga_multicorrelator_8sc::fpga_compute_code_shift_parameters(void) void Fpga_Multicorrelator_8sc::fpga_compute_code_shift_parameters(void)
{ {
float temp_calculation; float temp_calculation;
int32_t i; int32_t i;
//printf("ppp d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips);
for (i = 0; i < d_n_correlators; i++) for (i = 0; i < d_n_correlators; i++)
{ {
//printf("ppp d_shifts_chips %d = %f\n", i, d_shifts_chips[i]);
//printf("ppp d_code_samples_per_chip = %d\n", d_code_samples_per_chip);
temp_calculation = floor( temp_calculation = floor(
d_shifts_chips[i] - d_rem_code_phase_chips); d_shifts_chips[i] - d_rem_code_phase_chips);
//printf("ppp d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips);
//printf("ppp temp calculation %d = %f ================================ \n", i, temp_calculation);
if (temp_calculation < 0) if (temp_calculation < 0)
{ {
temp_calculation = temp_calculation + (d_code_length_chips * d_code_samples_per_chip); // % operator does not work as in Matlab with negative numbers temp_calculation = temp_calculation + (d_code_length_chips * d_code_samples_per_chip); // % operator does not work as in Matlab with negative numbers
} }
//printf("ppp d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips);
//printf("ppp temp calculation %d = %f ================================ \n", i, temp_calculation);
d_initial_index[i] = static_cast<uint32_t>((static_cast<int32_t>(temp_calculation)) % (d_code_length_chips * d_code_samples_per_chip)); d_initial_index[i] = static_cast<uint32_t>((static_cast<int32_t>(temp_calculation)) % (d_code_length_chips * d_code_samples_per_chip));
//printf("ppp d_initial_index %d = %d\n", i, d_initial_index[i]);
temp_calculation = fmod(d_shifts_chips[i] - d_rem_code_phase_chips, temp_calculation = fmod(d_shifts_chips[i] - d_rem_code_phase_chips,
1.0); 1.0);
//printf("ppp fmod %d = fmod(%f, 1) = %f\n", i, d_shifts_chips[i] - d_rem_code_phase_chips, temp_calculation);
if (temp_calculation < 0) if (temp_calculation < 0)
{ {
temp_calculation = temp_calculation + 1.0; // fmod operator does not work as in Matlab with negative numbers temp_calculation = temp_calculation + 1.0; // fmod operator does not work as in Matlab with negative numbers
} }
d_initial_interp_counter[i] = static_cast<uint32_t>(floor(MAX_CODE_RESAMPLER_COUNTER * temp_calculation)); d_initial_interp_counter[i] = static_cast<uint32_t>(floor(MAX_CODE_RESAMPLER_COUNTER * temp_calculation));
//printf("ppp d_initial_interp_counter %d = %d\n", i, d_initial_interp_counter[i]);
//printf("MAX_CODE_RESAMPLER_COUNTER = %d\n", MAX_CODE_RESAMPLER_COUNTER);
} }
if (d_track_pilot) if (d_track_pilot)
{ {
//printf("tracking pilot !!!!!!!!!!!!!!!!\n");
temp_calculation = floor( temp_calculation = floor(
d_prompt_data_shift[0] - d_rem_code_phase_chips); d_prompt_data_shift[0] - d_rem_code_phase_chips);
@ -522,47 +349,37 @@ void fpga_multicorrelator_8sc::fpga_compute_code_shift_parameters(void)
} }
d_initial_interp_counter[d_n_correlators] = static_cast<uint32_t>(floor(MAX_CODE_RESAMPLER_COUNTER * temp_calculation)); d_initial_interp_counter[d_n_correlators] = static_cast<uint32_t>(floor(MAX_CODE_RESAMPLER_COUNTER * temp_calculation));
} }
//while(1);
} }
void fpga_multicorrelator_8sc::fpga_configure_code_parameters_in_fpga(void) void Fpga_Multicorrelator_8sc::fpga_configure_code_parameters_in_fpga(void)
{ {
int32_t i; int32_t i;
for (i = 0; i < d_n_correlators; i++) for (i = 0; i < d_n_correlators; i++)
{ {
//printf("www writing d map base %d = d_initial_index %d = %d\n", d_INITIAL_INDEX_REG_BASE_ADDR + i, i, d_initial_index[i]); d_map_base[INITIAL_INDEX_REG_BASE_ADDR + i] = d_initial_index[i];
d_map_base[d_INITIAL_INDEX_REG_BASE_ADDR + i] = d_initial_index[i]; d_map_base[INITIAL_INTERP_COUNTER_REG_BASE_ADDR + i] = d_initial_interp_counter[i];
//d_map_base[1 + d_n_correlators + i] = d_initial_interp_counter[i];
//printf("www writing d map base %d = d_initial_interp_counter %d = %d\n", d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + i, i, d_initial_interp_counter[i]);
d_map_base[d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + i] = d_initial_interp_counter[i];
} }
if (d_track_pilot) if (d_track_pilot)
{ {
//printf("www writing d map base %d = d_initial_index %d = %d\n", d_INITIAL_INDEX_REG_BASE_ADDR + d_n_correlators, d_n_correlators, d_initial_index[d_n_correlators]); d_map_base[INITIAL_INDEX_REG_BASE_ADDR + d_n_correlators] = d_initial_index[d_n_correlators];
d_map_base[d_INITIAL_INDEX_REG_BASE_ADDR + d_n_correlators] = d_initial_index[d_n_correlators]; d_map_base[INITIAL_INTERP_COUNTER_REG_BASE_ADDR + d_n_correlators] = d_initial_interp_counter[d_n_correlators];
//d_map_base[1 + d_n_correlators + i] = d_initial_interp_counter[i];
//printf("www writing d map base %d = d_initial_interp_counter %d = %d\n", d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + d_n_correlators, d_n_correlators, d_initial_interp_counter[d_n_correlators]);
d_map_base[d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + d_n_correlators] = d_initial_interp_counter[d_n_correlators];
} }
//printf("www writing d map base %d = d_code_length_chips*d_code_samples_per_chip - 1 = %d\n", d_CODE_LENGTH_MINUS_1_REG_ADDR, (d_code_length_chips*d_code_samples_per_chip) - 1); d_map_base[CODE_LENGTH_MINUS_1_REG_ADDR] = (d_code_length_chips * d_code_samples_per_chip) - 1; // number of samples - 1
d_map_base[d_CODE_LENGTH_MINUS_1_REG_ADDR] = (d_code_length_chips * d_code_samples_per_chip) - 1; // number of samples - 1
} }
void fpga_multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(void) void Fpga_Multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(void)
{ {
float d_rem_carrier_phase_in_rad_temp; float d_rem_carrier_phase_in_rad_temp;
d_code_phase_step_chips_num = static_cast<uint32_t>(roundf(MAX_CODE_RESAMPLER_COUNTER * d_code_phase_step_chips)); d_code_phase_step_chips_num = static_cast<uint32_t>(roundf(MAX_CODE_RESAMPLER_COUNTER * d_code_phase_step_chips));
if (d_code_phase_step_chips > 1.0) if (d_code_phase_step_chips > 1.0)
{ {
printf("Warning : d_code_phase_step_chips = %f cannot be bigger than one\n", d_code_phase_step_chips); std::cout << "Warning : d_code_phase_step_chips = " << d_code_phase_step_chips << " cannot be bigger than one" << std::endl;
} }
//printf("d_rem_carrier_phase_in_rad = %f\n", d_rem_carrier_phase_in_rad);
if (d_rem_carrier_phase_in_rad > M_PI) if (d_rem_carrier_phase_in_rad > M_PI)
{ {
d_rem_carrier_phase_in_rad_temp = -2 * M_PI + d_rem_carrier_phase_in_rad; d_rem_carrier_phase_in_rad_temp = -2 * M_PI + d_rem_carrier_phase_in_rad;
@ -584,158 +401,77 @@ void fpga_multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(void)
d_phase_step_rad_int = static_cast<int32_t>(roundf( d_phase_step_rad_int = static_cast<int32_t>(roundf(
(fabs(d_phase_step_rad) / M_PI) * pow(2, PHASE_CARR_NBITS_FRAC))); // the FPGA accepts a range for the phase step between -pi and +pi (fabs(d_phase_step_rad) / M_PI) * pow(2, PHASE_CARR_NBITS_FRAC))); // the FPGA accepts a range for the phase step between -pi and +pi
//printf("d_phase_step_rad_int = %d\n", d_phase_step_rad_int);
if (d_phase_step_rad < 0) if (d_phase_step_rad < 0)
{ {
d_phase_step_rad_int = -d_phase_step_rad_int; d_phase_step_rad_int = -d_phase_step_rad_int;
} }
//printf("d_phase_step_rad_int = %d\n", d_phase_step_rad_int);
} }
void fpga_multicorrelator_8sc::fpga_configure_signal_parameters_in_fpga(void) void Fpga_Multicorrelator_8sc::fpga_configure_signal_parameters_in_fpga(void)
{ {
//printf("www d map base %d = d_code_phase_step_chips_num = %d\n", d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR, d_code_phase_step_chips_num); d_map_base[CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR] = d_code_phase_step_chips_num;
d_map_base[d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR] = d_code_phase_step_chips_num;
//printf("www d map base %d = d_correlator_length_samples - 1 = %d\n", d_NSAMPLES_MINUS_1_REG_ADDR, d_correlator_length_samples - 1); d_map_base[NSAMPLES_MINUS_1_REG_ADDR] = d_correlator_length_samples - 1;
d_map_base[d_NSAMPLES_MINUS_1_REG_ADDR] = d_correlator_length_samples - 1;
//printf("www d map base %d = d_rem_carr_phase_rad_int = %d\n", d_REM_CARR_PHASE_RAD_REG_ADDR, d_rem_carr_phase_rad_int); d_map_base[REM_CARR_PHASE_RAD_REG_ADDR] = d_rem_carr_phase_rad_int;
d_map_base[d_REM_CARR_PHASE_RAD_REG_ADDR] = d_rem_carr_phase_rad_int;
//printf("www d map base %d = d_phase_step_rad_int = %d\n", d_PHASE_STEP_RAD_REG_ADDR, d_phase_step_rad_int); d_map_base[PHASE_STEP_RAD_REG_ADDR] = d_phase_step_rad_int;
d_map_base[d_PHASE_STEP_RAD_REG_ADDR] = d_phase_step_rad_int;
} }
void fpga_multicorrelator_8sc::fpga_launch_multicorrelator_fpga(void) void Fpga_Multicorrelator_8sc::fpga_launch_multicorrelator_fpga(void)
{ {
// enable interrupts // enable interrupts
int32_t reenable = 1; int32_t reenable = 1;
write(d_device_descriptor, reinterpret_cast<void *>(&reenable), sizeof(int32_t)); write(d_device_descriptor, reinterpret_cast<void *>(&reenable), sizeof(int32_t));
// writing 1 to reg 14 launches the tracking // writing 1 to reg 14 launches the tracking
//printf("www writing 1 to d map base %d = start flag\n", d_START_FLAG_ADDR); d_map_base[START_FLAG_ADDR] = 1;
d_map_base[d_START_FLAG_ADDR] = 1;
//while(1);
} }
void fpga_multicorrelator_8sc::read_tracking_gps_results(void) void Fpga_Multicorrelator_8sc::read_tracking_gps_results(void)
{ {
int32_t readval_real; int32_t readval_real;
int32_t readval_imag; int32_t readval_imag;
int32_t k; int32_t k;
//printf("www reading trk results\n");
for (k = 0; k < d_n_correlators; k++) for (k = 0; k < d_n_correlators; k++)
{ {
readval_real = d_map_base[d_RESULT_REG_REAL_BASE_ADDR + k]; readval_real = d_map_base[RESULT_REG_REAL_BASE_ADDR + k];
//printf("read real before checking d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_real); readval_imag = d_map_base[RESULT_REG_IMAG_BASE_ADDR + k];
//// if (readval_real > debug_max_readval_real[k])
//// {
//// debug_max_readval_real[k] = readval_real;
//// }
// if (readval_real >= d_result_SAT_value) // 0x100000 (21 bits two's complement)
// {
// readval_real = -2*d_result_SAT_value + readval_real;
// }
//// if (readval_real > debug_max_readval_real_after_check[k])
//// {
//// debug_max_readval_real_after_check[k] = readval_real;
//// }
//printf("read real d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_real);
readval_imag = d_map_base[d_RESULT_REG_IMAG_BASE_ADDR + k];
//printf("read imag before checking d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_imag);
//// if (readval_imag > debug_max_readval_imag[k])
//// {
//// debug_max_readval_imag[k] = readval_imag;
//// }
//
// if (readval_imag >= d_result_SAT_value) // 0x100000 (21 bits two's complement)
// {
// readval_imag = -2*d_result_SAT_value + readval_imag;
// }
//// if (readval_imag > debug_max_readval_imag_after_check[k])
//// {
//// debug_max_readval_imag_after_check[k] = readval_real;
//// }
//printf("read imag d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_imag);
d_corr_out[k] = gr_complex(readval_real, readval_imag); d_corr_out[k] = gr_complex(readval_real, readval_imag);
// if (printcounter > 100)
// {
// printcounter = 0;
// for (int32_t ll=0;ll<d_n_correlators;ll++)
// {
// printf("debug_max_readval_real %d = %d\n", ll, debug_max_readval_real[ll]);
// printf("debug_max_readval_imag %d = %d\n", ll, debug_max_readval_imag[ll]);
// printf("debug_max_readval_real_%d after_check = %d\n", ll, debug_max_readval_real_after_check[ll]);
// printf("debug_max_readval_imag_%d after_check = %d\n", ll, debug_max_readval_imag_after_check[ll]);
// }
//
// }
// else
// {
// printcounter = printcounter + 1;
// }
} }
if (d_track_pilot) if (d_track_pilot)
{ {
//printf("reading pilot !!!\n"); readval_real = d_map_base[RESULT_REG_REAL_BASE_ADDR + d_n_correlators];
readval_real = d_map_base[d_RESULT_REG_DATA_REAL_BASE_ADDR]; readval_imag = d_map_base[RESULT_REG_IMAG_BASE_ADDR + d_n_correlators];
// if (readval_real >= d_result_SAT_value) // 0x100000 (21 bits two's complement)
// {
// readval_real = -2*d_result_SAT_value + readval_real;
// }
readval_imag = d_map_base[d_RESULT_REG_DATA_IMAG_BASE_ADDR];
// if (readval_imag >= d_result_SAT_value) // 0x100000 (21 bits two's complement)
// {
// readval_imag = -2*d_result_SAT_value + readval_imag;
// }
d_Prompt_Data[0] = gr_complex(readval_real, readval_imag); d_Prompt_Data[0] = gr_complex(readval_real, readval_imag);
} }
} }
void fpga_multicorrelator_8sc::unlock_channel(void) void Fpga_Multicorrelator_8sc::unlock_channel(void)
{ {
// unlock the channel to let the next samples go through // unlock the channel to let the next samples go through
//printf("www writing 1 to d map base %d = drop samples\n", d_DROP_SAMPLES_REG_ADDR); d_map_base[DROP_SAMPLES_REG_ADDR] = 1; // unlock the channel
d_map_base[d_DROP_SAMPLES_REG_ADDR] = 1; // unlock the channel d_map_base[STOP_TRACKING_REG_ADDR] = 1; // set the tracking module back to idle
} }
void fpga_multicorrelator_8sc::close_device() void Fpga_Multicorrelator_8sc::close_device()
{ {
auto *aux = const_cast<uint32_t *>(d_map_base); auto *aux = const_cast<uint32_t *>(d_map_base);
if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1) if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1)
{ {
printf("Failed to unmap memory uio\n"); std::cout << "Failed to unmap memory uio" << std::endl;
} }
close(d_device_descriptor); close(d_device_descriptor);
} }
void fpga_multicorrelator_8sc::lock_channel(void) void Fpga_Multicorrelator_8sc::lock_channel(void)
{ {
// lock the channel for processing // lock the channel for processing
//printf("www writing 0 to d map base %d = drop samples\n", d_DROP_SAMPLES_REG_ADDR); d_map_base[DROP_SAMPLES_REG_ADDR] = 0; // lock the channel
d_map_base[d_DROP_SAMPLES_REG_ADDR] = 0; // lock the channel
} }
//void fpga_multicorrelator_8sc::read_sample_counters(int32_t *sample_counter, int32_t *secondary_sample_counter, int32_t *counter_corr_0_in, int32_t *counter_corr_0_out)
//{
// *sample_counter = d_map_base[11];
// *secondary_sample_counter = d_map_base[8];
// *counter_corr_0_in = d_map_base[10];
// *counter_corr_0_out = d_map_base[9];
//
//}
//void fpga_multicorrelator_8sc::reset_multicorrelator(void)
//{
// d_map_base[14] = 2; // writing a 2 to d_map_base[14] resets the multicorrelator
//}

View File

@ -1,8 +1,8 @@
/*! /*!
* \file fpga_multicorrelator_8sc.h * \file fpga_multicorrelator_8sc.h
* \brief High optimized FPGA vector correlator class for lv_16sc_t (short int32_t complex) * \brief High optimized FPGA vector correlator class
* \authors <ul> * \authors <ul>
* <li> Marc Majoral, 2017. mmajoral(at)cttc.cat * <li> Marc Majoral, 2019. mmajoral(at)cttc.cat
* <li> Javier Arribas, 2016. jarribas(at)cttc.es * <li> Javier Arribas, 2016. jarribas(at)cttc.es
* </ul> * </ul>
* *
@ -11,7 +11,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -41,32 +41,49 @@
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <cstdint> #include <cstdint>
#define MAX_LENGTH_DEVICEIO_NAME 50 // FPGA register addresses
// write addresses
#define CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR 0
#define INITIAL_INDEX_REG_BASE_ADDR 1
#define INITIAL_INTERP_COUNTER_REG_BASE_ADDR 7
#define NSAMPLES_MINUS_1_REG_ADDR 13
#define CODE_LENGTH_MINUS_1_REG_ADDR 14
#define REM_CARR_PHASE_RAD_REG_ADDR 15
#define PHASE_STEP_RAD_REG_ADDR 16
#define PROG_MEMS_ADDR 17
#define DROP_SAMPLES_REG_ADDR 18
#define INITIAL_COUNTER_VALUE_REG_ADDR_LSW 19
#define INITIAL_COUNTER_VALUE_REG_ADDR_MSW 20
#define STOP_TRACKING_REG_ADDR 23
#define START_FLAG_ADDR 30
// read-write addresses
#define TEST_REG_ADDR 31
// read addresses
#define RESULT_REG_REAL_BASE_ADDR 1
#define RESULT_REG_IMAG_BASE_ADDR 7
#define SAMPLE_COUNTER_REG_ADDR_LSW 13
#define SAMPLE_COUNTER_REG_ADDR_MSW 14
/*! /*!
* \brief Class that implements carrier wipe-off and correlators. * \brief Class that implements carrier wipe-off and correlators.
*/ */
class fpga_multicorrelator_8sc class Fpga_Multicorrelator_8sc
{ {
public: public:
fpga_multicorrelator_8sc(int32_t n_correlators, std::string device_name, Fpga_Multicorrelator_8sc(int32_t n_correlators, std::string device_name,
uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, uint32_t multicorr_type, uint32_t code_samples_per_chip); uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, uint32_t multicorr_type, uint32_t code_samples_per_chip);
~fpga_multicorrelator_8sc(); ~Fpga_Multicorrelator_8sc();
//bool set_output_vectors(gr_complex* corr_out);
void set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data); void set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data);
// bool set_local_code_and_taps(
// int32_t code_length_chips, const int* local_code_in,
// float *shifts_chips, int32_t PRN);
//bool set_local_code_and_taps(
void set_local_code_and_taps( void set_local_code_and_taps(
// int32_t code_length_chips,
float *shifts_chips, float *prompt_data_shift, int32_t PRN); float *shifts_chips, float *prompt_data_shift, int32_t PRN);
//bool set_output_vectors(lv_16sc_t* corr_out);
void update_local_code(float rem_code_phase_chips); void update_local_code(float rem_code_phase_chips);
//bool Carrier_wipeoff_multicorrelator_resampler(
void Carrier_wipeoff_multicorrelator_resampler( void Carrier_wipeoff_multicorrelator_resampler(
float rem_carrier_phase_in_rad, float phase_step_rad, float rem_carrier_phase_in_rad, float phase_step_rad,
float carrier_phase_rate_step_rad,
float rem_code_phase_chips, float code_phase_step_chips, float rem_code_phase_chips, float code_phase_step_chips,
float code_phase_rate_step_chips,
int32_t signal_length_samples); int32_t signal_length_samples);
bool free(); bool free();
void set_channel(uint32_t channel); void set_channel(uint32_t channel);
@ -74,10 +91,8 @@ public:
uint64_t read_sample_counter(); uint64_t read_sample_counter();
void lock_channel(void); void lock_channel(void);
void unlock_channel(void); void unlock_channel(void);
//void read_sample_counters(int32_t *sample_counter, int32_t *secondary_sample_counter, int32_t *counter_corr_0_in, int32_t *counter_corr_0_out); // debug
private: private:
//const int32_t *d_local_code_in;
gr_complex *d_corr_out; gr_complex *d_corr_out;
gr_complex *d_Prompt_Data; gr_complex *d_Prompt_Data;
float *d_shifts_chips; float *d_shifts_chips;
@ -113,37 +128,11 @@ private:
int32_t *d_ca_codes; int32_t *d_ca_codes;
int32_t *d_data_codes; int32_t *d_data_codes;
//uint32_t d_code_length; // nominal number of chips
uint32_t d_code_samples_per_chip; uint32_t d_code_samples_per_chip;
bool d_track_pilot; bool d_track_pilot;
uint32_t d_multicorr_type; uint32_t d_multicorr_type;
// register addresses
// write-only regs
uint32_t d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR;
uint32_t d_INITIAL_INDEX_REG_BASE_ADDR;
uint32_t d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR;
uint32_t d_NSAMPLES_MINUS_1_REG_ADDR;
uint32_t d_CODE_LENGTH_MINUS_1_REG_ADDR;
uint32_t d_REM_CARR_PHASE_RAD_REG_ADDR;
uint32_t d_PHASE_STEP_RAD_REG_ADDR;
uint32_t d_PROG_MEMS_ADDR;
uint32_t d_DROP_SAMPLES_REG_ADDR;
uint32_t d_INITIAL_COUNTER_VALUE_REG_ADDR_LSW;
uint32_t d_INITIAL_COUNTER_VALUE_REG_ADDR_MSW;
uint32_t d_START_FLAG_ADDR;
// read-write regs
uint32_t d_TEST_REG_ADDR;
// read-only regs
uint32_t d_RESULT_REG_REAL_BASE_ADDR;
uint32_t d_RESULT_REG_IMAG_BASE_ADDR;
uint32_t d_RESULT_REG_DATA_REAL_BASE_ADDR;
uint32_t d_RESULT_REG_DATA_IMAG_BASE_ADDR;
uint32_t d_SAMPLE_COUNTER_REG_ADDR_LSW;
uint32_t d_SAMPLE_COUNTER_REG_ADDR_MSW;
// private functions // private functions
uint32_t fpga_acquisition_test_register(uint32_t writeval); uint32_t fpga_acquisition_test_register(uint32_t writeval);
void fpga_configure_tracking_gps_local_code(int32_t PRN); void fpga_configure_tracking_gps_local_code(int32_t PRN);
@ -153,17 +142,7 @@ private:
void fpga_configure_signal_parameters_in_fpga(void); void fpga_configure_signal_parameters_in_fpga(void);
void fpga_launch_multicorrelator_fpga(void); void fpga_launch_multicorrelator_fpga(void);
void read_tracking_gps_results(void); void read_tracking_gps_results(void);
//void reset_multicorrelator(void);
void close_device(void); void close_device(void);
uint32_t d_result_SAT_value;
int32_t debug_max_readval_real[5] = {0, 0, 0, 0, 0};
int32_t debug_max_readval_imag[5] = {0, 0, 0, 0, 0};
int32_t debug_max_readval_real_after_check[5] = {0, 0, 0, 0, 0};
int32_t debug_max_readval_imag_after_check[5] = {0, 0, 0, 0, 0};
int32_t printcounter = 0;
}; };
#endif /* GNSS_SDR_FPGA_MULTICORRELATOR_H_ */ #endif /* GNSS_SDR_FPGA_MULTICORRELATOR_H_ */

View File

@ -273,12 +273,11 @@ int ControlThread::run()
cmd_interface_.set_pvt(flowgraph_->get_pvt()); cmd_interface_.set_pvt(flowgraph_->get_pvt());
cmd_interface_thread_ = std::thread(&ControlThread::telecommand_listener, this); cmd_interface_thread_ = std::thread(&ControlThread::telecommand_listener, this);
bool enable_FPGA = configuration_->property("Channel.enable_FPGA", false); #ifdef ENABLE_FPGA
if (enable_FPGA == true) // Create a task for the acquisition such that id doesn't block the flow of the control thread
{ fpga_helper_thread_ = boost::thread(&GNSSFlowgraph::start_acquisition_helper,
flowgraph_->start_acquisition_helper(); flowgraph_);
} #endif
// Main loop to read and process the control messages // Main loop to read and process the control messages
while (flowgraph_->running() && !stop_) while (flowgraph_->running() && !stop_)
{ {
@ -294,12 +293,23 @@ int ControlThread::run()
stop_ = true; stop_ = true;
flowgraph_->disconnect(); flowgraph_->disconnect();
#ifdef ENABLE_FPGA
// trigger a HW reset
// The HW reset causes any HW accelerator module that is waiting for more samples to complete its calculations
// to trigger an interrupt and finish its signal processing tasks immediately. In this way all SW threads that
// are waiting for interrupts in the HW can exit in a normal way.
flowgraph_->perform_hw_reset();
fpga_helper_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000));
#endif
std::this_thread::sleep_for(std::chrono::milliseconds(500)); std::this_thread::sleep_for(std::chrono::milliseconds(500));
// Terminate keyboard thread // Terminate keyboard thread
pthread_t id = keyboard_thread_.native_handle(); pthread_t id = keyboard_thread_.native_handle();
keyboard_thread_.detach(); keyboard_thread_.detach();
pthread_cancel(id); pthread_cancel(id);
LOG(INFO) << "Flowgraph stopped";
if (restart_) if (restart_)
{ {
return 42; // signal the gnss-sdr-harness.sh to restart the receiver program return 42; // signal the gnss-sdr-harness.sh to restart the receiver program

View File

@ -95,7 +95,6 @@ public:
*/ */
void set_control_queue(const gr::msg_queue::sptr control_queue); // NOLINT(performance-unnecessary-value-param) void set_control_queue(const gr::msg_queue::sptr control_queue); // NOLINT(performance-unnecessary-value-param)
unsigned int processed_control_messages() unsigned int processed_control_messages()
{ {
return processed_control_messages_; return processed_control_messages_;
@ -168,6 +167,9 @@ private:
bool delete_configuration_; bool delete_configuration_;
unsigned int processed_control_messages_; unsigned int processed_control_messages_;
unsigned int applied_actions_; unsigned int applied_actions_;
boost::thread fpga_helper_thread_;
std::thread keyboard_thread_; std::thread keyboard_thread_;
std::thread sysv_queue_thread_; std::thread sysv_queue_thread_;
std::thread gps_acq_assist_data_collector_thread_; std::thread gps_acq_assist_data_collector_thread_;

View File

@ -11,7 +11,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver

View File

@ -9,7 +9,7 @@
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
* *
* GNSS-SDR is a software defined Global Navigation * GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver * Satellite Systems receiver
@ -50,6 +50,7 @@
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <set> #include <set>
#include <thread>
#include <utility> #include <utility>
#ifdef GR_GREATER_38 #ifdef GR_GREATER_38
#include <gnuradio/filter/fir_filter_blk.h> #include <gnuradio/filter/fir_filter_blk.h>
@ -123,6 +124,7 @@ void GNSSFlowgraph::connect()
return; return;
} }
#ifndef ENABLE_FPGA
for (int i = 0; i < sources_count_; i++) for (int i = 0; i < sources_count_; i++)
{ {
if (configuration_->property(sig_source_.at(i)->role() + ".enable_FPGA", false) == false) if (configuration_->property(sig_source_.at(i)->role() + ".enable_FPGA", false) == false)
@ -141,6 +143,7 @@ void GNSSFlowgraph::connect()
} }
} }
// Signal Source > Signal conditioner > // Signal Source > Signal conditioner >
for (unsigned int i = 0; i < sig_conditioner_.size(); i++) for (unsigned int i = 0; i < sig_conditioner_.size(); i++)
{ {
@ -159,7 +162,7 @@ void GNSSFlowgraph::connect()
} }
} }
} }
#endif
for (unsigned int i = 0; i < channels_count_; i++) for (unsigned int i = 0; i < channels_count_; i++)
{ {
try try
@ -205,11 +208,10 @@ void GNSSFlowgraph::connect()
int RF_Channels = 0; int RF_Channels = 0;
int signal_conditioner_ID = 0; int signal_conditioner_ID = 0;
#ifndef ENABLE_FPGA
for (int i = 0; i < sources_count_; i++) for (int i = 0; i < sources_count_; i++)
{
//FPGA Accelerators do not need signal sources or conditioners
//as the samples are feed directly to the FPGA fabric, so, if enabled, do not connect any source
if (configuration_->property(sig_source_.at(i)->role() + ".enable_FPGA", false) == false)
{ {
try try
{ {
@ -271,12 +273,13 @@ void GNSSFlowgraph::connect()
return; return;
} }
} }
}
DLOG(INFO) << "Signal source connected to signal conditioner"; DLOG(INFO) << "Signal source connected to signal conditioner";
bool FPGA_enabled = configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false);
#endif
#if ENABLE_FPGA #if ENABLE_FPGA
if (FPGA_enabled == false)
if (configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false) == false)
{ {
//connect the signal source to sample counter //connect the signal source to sample counter
//connect the sample counter to Observables //connect the sample counter to Observables
@ -352,13 +355,15 @@ void GNSSFlowgraph::connect()
return; return;
} }
#endif #endif
// Signal conditioner (selected_signal_source) >> channels (i) (dependent of their associated SignalSource_ID) // Signal conditioner (selected_signal_source) >> channels (i) (dependent of their associated SignalSource_ID)
int selected_signal_conditioner_ID = 0; int selected_signal_conditioner_ID = 0;
bool use_acq_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false); bool use_acq_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
uint32_t fs = configuration_->property("GNSS-SDR.internal_fs_sps", 0); uint32_t fs = configuration_->property("GNSS-SDR.internal_fs_sps", 0);
for (unsigned int i = 0; i < channels_count_; i++) for (unsigned int i = 0; i < channels_count_; i++)
{ {
if (FPGA_enabled == false) #ifndef ENABLE_FPGA
if (configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false) == false)
{ {
try try
{ {
@ -497,6 +502,7 @@ void GNSSFlowgraph::connect()
DLOG(INFO) << "signal conditioner " << selected_signal_conditioner_ID << " connected to channel " << i; DLOG(INFO) << "signal conditioner " << selected_signal_conditioner_ID << " connected to channel " << i;
} }
#endif
// Signal Source > Signal conditioner >> Channels >> Observables // Signal Source > Signal conditioner >> Channels >> Observables
try try
{ {
@ -655,16 +661,15 @@ void GNSSFlowgraph::connect()
} }
} }
#ifndef ENABLE_FPGA
// Activate acquisition in enabled channels // Activate acquisition in enabled channels
for (unsigned int i = 0; i < channels_count_; i++) for (unsigned int i = 0; i < channels_count_; i++)
{ {
LOG(INFO) << "Channel " << i << " assigned to " << channels_.at(i)->get_signal(); LOG(INFO) << "Channel " << i << " assigned to " << channels_.at(i)->get_signal();
if (channels_state_[i] == 1) if (channels_state_[i] == 1)
{
if (FPGA_enabled == false)
{ {
channels_.at(i)->start_acquisition(); channels_.at(i)->start_acquisition();
}
LOG(INFO) << "Channel " << i << " connected to observables and ready for acquisition"; LOG(INFO) << "Channel " << i << " connected to observables and ready for acquisition";
} }
else else
@ -672,6 +677,7 @@ void GNSSFlowgraph::connect()
LOG(INFO) << "Channel " << i << " connected to observables in standby mode"; LOG(INFO) << "Channel " << i << " connected to observables in standby mode";
} }
} }
#endif
connected_ = true; connected_ = true;
LOG(INFO) << "Flowgraph connected"; LOG(INFO) << "Flowgraph connected";
@ -693,6 +699,66 @@ void GNSSFlowgraph::disconnect()
int RF_Channels = 0; int RF_Channels = 0;
int signal_conditioner_ID = 0; int signal_conditioner_ID = 0;
#ifdef ENABLE_FPGA
if (configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false) == false)
{
for (int i = 0; i < sources_count_; i++)
{
try
{
// TODO: Remove this array implementation and create generic multistream connector
// (if a signal source has more than 1 stream, then connect it to the multistream signal conditioner)
if (sig_source_.at(i)->implementation() == "Raw_Array_Signal_Source")
{
//Multichannel Array
for (int j = 0; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS; j++)
{
top_block_->disconnect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(i)->get_left_block(), j);
}
}
else
{
// TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
// Include GetRFChannels in the interface to avoid read config parameters here
// read the number of RF channels for each front-end
RF_Channels = configuration_->property(sig_source_.at(i)->role() + ".RF_channels", 1);
for (int j = 0; j < RF_Channels; j++)
{
if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1)
{
top_block_->disconnect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0);
}
else
{
if (j == 0)
{
// RF_channel 0 backward compatibility with single channel sources
top_block_->disconnect(sig_source_.at(i)->get_right_block(), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0);
}
else
{
// Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call)
top_block_->disconnect(sig_source_.at(i)->get_right_block(j), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0);
}
}
signal_conditioner_ID++;
}
}
}
catch (const std::exception& e)
{
LOG(INFO) << "Can't disconnect signal source " << i << " to signal conditioner " << i << ": " << e.what();
top_block_->disconnect_all();
return;
}
}
}
#else
for (int i = 0; i < sources_count_; i++) for (int i = 0; i < sources_count_; i++)
{ {
try try
@ -744,10 +810,10 @@ void GNSSFlowgraph::disconnect()
return; return;
} }
} }
#endif
#if ENABLE_FPGA #ifdef ENABLE_FPGA
bool FPGA_enabled = configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false); if (configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false) == false)
if (FPGA_enabled == false)
{ {
// disconnect the signal source to sample counter // disconnect the signal source to sample counter
// disconnect the sample counter to Observables // disconnect the sample counter to Observables
@ -808,6 +874,7 @@ void GNSSFlowgraph::disconnect()
top_block_->disconnect_all(); top_block_->disconnect_all();
return; return;
} }
#ifndef ENABLE_FPGA
try try
{ {
top_block_->disconnect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0, top_block_->disconnect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
@ -819,7 +886,7 @@ void GNSSFlowgraph::disconnect()
top_block_->disconnect_all(); top_block_->disconnect_all();
return; return;
} }
#endif
// Signal Source > Signal conditioner >> Channels >> Observables // Signal Source > Signal conditioner >> Channels >> Observables
try try
{ {
@ -1060,7 +1127,14 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
} }
acq_channels_count_++; acq_channels_count_++;
DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str(); DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str();
#ifndef ENABLE_FPGA
channels_[ch_index]->start_acquisition(); channels_[ch_index]->start_acquisition();
#else
// create a task for the FPGA such that it doesn't stop the flow
std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[ch_index]);
tmp_thread.detach();
#endif
} }
DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index]; DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index];
} }
@ -1131,7 +1205,13 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
} }
acq_channels_count_++; acq_channels_count_++;
DLOG(INFO) << "Channel " << i << " Starting acquisition " << channels_[i]->get_signal().get_satellite() << ", Signal " << channels_[i]->get_signal().get_signal_str(); DLOG(INFO) << "Channel " << i << " Starting acquisition " << channels_[i]->get_signal().get_satellite() << ", Signal " << channels_[i]->get_signal().get_signal_str();
#ifndef ENABLE_FPGA
channels_[i]->start_acquisition(); channels_[i]->start_acquisition();
#else
// create a task for the FPGA such that it doesn't stop the flow
std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[i]);
tmp_thread.detach();
#endif
} }
DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i]; DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i];
} }
@ -1146,7 +1226,13 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
channels_state_[who] = 1; channels_state_[who] = 1;
acq_channels_count_++; acq_channels_count_++;
LOG(INFO) << "Channel " << who << " Starting acquisition " << channels_[who]->get_signal().get_satellite() << ", Signal " << channels_[who]->get_signal().get_signal_str(); LOG(INFO) << "Channel " << who << " Starting acquisition " << channels_[who]->get_signal().get_satellite() << ", Signal " << channels_[who]->get_signal().get_signal_str();
#ifndef ENABLE_FPGA
channels_[who]->start_acquisition(); channels_[who]->start_acquisition();
#else
// create a task for the FPGA such that it doesn't stop the flow
std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[who]);
tmp_thread.detach();
#endif
} }
else else
{ {
@ -1275,7 +1361,13 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
} }
acq_channels_count_++; acq_channels_count_++;
DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str(); DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str();
#ifndef ENABLE_FPGA
channels_[ch_index]->start_acquisition(); channels_[ch_index]->start_acquisition();
#else
// create a task for the FPGA such that it doesn't stop the flow
std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[ch_index]);
tmp_thread.detach();
#endif
} }
DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index]; DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index];
} }
@ -1303,7 +1395,13 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
} }
acq_channels_count_++; acq_channels_count_++;
DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str(); DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str();
#ifndef ENABLE_FPGA
channels_[ch_index]->start_acquisition(); channels_[ch_index]->start_acquisition();
#else
// create a task for the FPGA such that it doesn't stop the flow
std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[ch_index]);
tmp_thread.detach();
#endif
} }
DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index]; DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index];
} }
@ -1332,7 +1430,13 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
} }
acq_channels_count_++; acq_channels_count_++;
DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str(); DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str();
#ifndef ENABLE_FPGA
channels_[ch_index]->start_acquisition(); channels_[ch_index]->start_acquisition();
#else
// create a task for the FPGA such that it doesn't stop the flow
std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[ch_index]);
tmp_thread.detach();
#endif
} }
DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index]; DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index];
} }
@ -1412,6 +1516,7 @@ void GNSSFlowgraph::set_configuration(std::shared_ptr<ConfigurationInterface> co
configuration_ = std::move(configuration); configuration_ = std::move(configuration);
} }
#ifdef ENABLE_FPGA
void GNSSFlowgraph::start_acquisition_helper() void GNSSFlowgraph::start_acquisition_helper()
{ {
@ -1425,6 +1530,16 @@ void GNSSFlowgraph::start_acquisition_helper()
} }
void GNSSFlowgraph::perform_hw_reset()
{
// a stop acquisition command causes the SW to reset the HW
std::shared_ptr<Channel> channel_ptr;
channel_ptr = std::dynamic_pointer_cast<Channel>(channels_.at(0));
channel_ptr->acquisition()->stop_acquisition();
}
#endif
void GNSSFlowgraph::init() void GNSSFlowgraph::init()
{ {
/* /*

View File

@ -95,9 +95,11 @@ public:
void disconnect(); void disconnect();
void wait(); void wait();
#ifdef ENABLE_FPGA
void start_acquisition_helper(); void start_acquisition_helper();
void perform_hw_reset();
#endif
/*! /*!
* \brief Applies an action to the flow graph * \brief Applies an action to the flow graph
* *

View File

@ -343,18 +343,11 @@ bool Galileo_Navigation_Message::read_navigation_bool(std::bitset<GALILEO_DATA_J
void Galileo_Navigation_Message::split_page(std::string page_string, int32_t flag_even_word) void Galileo_Navigation_Message::split_page(std::string page_string, int32_t flag_even_word)
{ {
// ToDo: Clean all the tests and create an independent google test code for the telemetry decoder.
//char correct_tail[7]="011110"; //the viterbi decoder output change the tail to this value (why?)
//char correct_tail[7]="000000";
int32_t Page_type = 0; int32_t Page_type = 0;
// std::cout << "Start decoding Galileo I/NAV " << std::endl;
if (page_string.at(0) == '1') // if page is odd if (page_string.at(0) == '1') // if page is odd
{ {
// std::cout<< "page_string.at(0) split page="<<page_string.at(0) << std::endl;
const std::string& page_Odd = page_string; const std::string& page_Odd = page_string;
// std::cout<<"Page odd string in split page"<< std::endl << page_Odd << std::endl;
if (flag_even_word == 1) // An odd page has been received but the previous even page is kept in memory and it is considered to join pages if (flag_even_word == 1) // An odd page has been received but the previous even page is kept in memory and it is considered to join pages
{ {
@ -364,10 +357,6 @@ void Galileo_Navigation_Message::split_page(std::string page_string, int32_t fla
std::string Page_type_even = page_INAV.substr(1, 1); std::string Page_type_even = page_INAV.substr(1, 1);
std::string nominal = "0"; std::string nominal = "0";
//if (Page_type_even.compare(nominal) != 0)
// std::cout << "Alert frame "<< std::endl;
//else std::cout << "Nominal Page" << std::endl;
std::string Data_k = page_INAV.substr(2, 112); std::string Data_k = page_INAV.substr(2, 112);
std::string Odd_bit = page_INAV.substr(114, 1); std::string Odd_bit = page_INAV.substr(114, 1);
std::string Page_type_Odd = page_INAV.substr(115, 1); std::string Page_type_Odd = page_INAV.substr(115, 1);
@ -388,10 +377,6 @@ void Galileo_Navigation_Message::split_page(std::string page_string, int32_t fla
std::bitset<GALILEO_DATA_FRAME_BITS> TLM_word_for_CRC_bits(TLM_word_for_CRC); std::bitset<GALILEO_DATA_FRAME_BITS> TLM_word_for_CRC_bits(TLM_word_for_CRC);
std::bitset<24> checksum(CRC_data); std::bitset<24> checksum(CRC_data);
//if (Tail_odd.compare(correct_tail) != 0)
// std::cout << "Tail odd is not correct!" << std::endl;
//else std::cout<<"Tail odd is correct!"<<std::endl;
if (CRC_test(TLM_word_for_CRC_bits, checksum.to_ulong()) == true) if (CRC_test(TLM_word_for_CRC_bits, checksum.to_ulong()) == true)
{ {
flag_CRC_test = true; flag_CRC_test = true;
@ -414,10 +399,6 @@ void Galileo_Navigation_Message::split_page(std::string page_string, int32_t fla
{ {
page_Even = page_string.substr(0, 114); page_Even = page_string.substr(0, 114);
std::string tail_Even = page_string.substr(114, 6); std::string tail_Even = page_string.substr(114, 6);
//std::cout << "tail_even_string: " << tail_Even <<std::endl;
//if (tail_Even.compare(correct_tail) != 0)
// std::cout << "Tail even is not correct!" << std::endl;
//else std::cout<<"Tail even is correct!"<< std::endl;
} }
} }
@ -429,14 +410,14 @@ bool Galileo_Navigation_Message::have_new_ephemeris() // Check if we have a new
// if all ephemeris pages have the same IOD, then they belong to the same block // if all ephemeris pages have the same IOD, then they belong to the same block
if ((IOD_nav_1 == IOD_nav_2) and (IOD_nav_3 == IOD_nav_4) and (IOD_nav_1 == IOD_nav_3)) if ((IOD_nav_1 == IOD_nav_2) and (IOD_nav_3 == IOD_nav_4) and (IOD_nav_1 == IOD_nav_3))
{ {
std::cout << "Ephemeris (1, 2, 3, 4) have been received and belong to the same batch" << std::endl; DLOG(INFO) << "Ephemeris (1, 2, 3, 4) have been received and belong to the same batch";
flag_ephemeris_1 = false; // clear the flag flag_ephemeris_1 = false; // clear the flag
flag_ephemeris_2 = false; // clear the flag flag_ephemeris_2 = false; // clear the flag
flag_ephemeris_3 = false; // clear the flag flag_ephemeris_3 = false; // clear the flag
flag_ephemeris_4 = false; // clear the flag flag_ephemeris_4 = false; // clear the flag
flag_all_ephemeris = true; flag_all_ephemeris = true;
IOD_ephemeris = IOD_nav_1; IOD_ephemeris = IOD_nav_1;
std::cout << "Batch number: " << IOD_ephemeris << std::endl; DLOG(INFO) << "Batch number: " << IOD_ephemeris;
return true; return true;
} }
} }

View File

@ -123,7 +123,7 @@ int main(int argc, char** argv)
boost::system::error_code ec; boost::system::error_code ec;
if (!boost::filesystem::create_directory(p, ec)) if (!boost::filesystem::create_directory(p, ec))
{ {
std::cout << "Could not create the " << FLAGS_log_dir << " folder. GNSS-SDR program ended." << std::endl; std::cerr << "Could not create the " << FLAGS_log_dir << " folder. GNSS-SDR program ended." << std::endl;
google::ShutDownCommandLineFlags(); google::ShutDownCommandLineFlags();
return 1; return 1;
} }
@ -144,8 +144,9 @@ int main(int argc, char** argv)
} }
catch (const boost::thread_resource_error& e) catch (const boost::thread_resource_error& e)
{ {
std::cout << "Failed to create boost thread." << std::endl; std::cerr << "Failed to create boost thread." << std::endl;
google::ShutDownCommandLineFlags(); google::ShutDownCommandLineFlags();
std::cout << "GNSS-SDR program ended." << std::endl;
return 1; return 1;
} }
catch (const boost::exception& e) catch (const boost::exception& e)
@ -153,12 +154,14 @@ int main(int argc, char** argv)
if (GOOGLE_STRIP_LOG == 0) if (GOOGLE_STRIP_LOG == 0)
{ {
LOG(WARNING) << "Boost exception: " << boost::diagnostic_information(e); LOG(WARNING) << "Boost exception: " << boost::diagnostic_information(e);
std::cerr << boost::diagnostic_information(e) << std::endl;
} }
else else
{ {
std::cerr << "Boost exception: " << boost::diagnostic_information(e) << std::endl; std::cerr << "Boost exception: " << boost::diagnostic_information(e) << std::endl;
} }
google::ShutDownCommandLineFlags(); google::ShutDownCommandLineFlags();
std::cout << "GNSS-SDR program ended." << std::endl;
return 1; return 1;
} }
catch (const std::exception& ex) catch (const std::exception& ex)
@ -166,12 +169,14 @@ int main(int argc, char** argv)
if (GOOGLE_STRIP_LOG == 0) if (GOOGLE_STRIP_LOG == 0)
{ {
LOG(WARNING) << "C++ Standard Library exception: " << ex.what(); LOG(WARNING) << "C++ Standard Library exception: " << ex.what();
std::cerr << ex.what() << std::endl;
} }
else else
{ {
std::cerr << "C++ Standard Library exception: " << ex.what() << std::endl; std::cerr << "C++ Standard Library exception: " << ex.what() << std::endl;
} }
google::ShutDownCommandLineFlags(); google::ShutDownCommandLineFlags();
std::cout << "GNSS-SDR program ended." << std::endl;
return 1; return 1;
} }
catch (...) catch (...)
@ -179,12 +184,14 @@ int main(int argc, char** argv)
if (GOOGLE_STRIP_LOG == 0) if (GOOGLE_STRIP_LOG == 0)
{ {
LOG(WARNING) << "Unexpected catch. This should not happen."; LOG(WARNING) << "Unexpected catch. This should not happen.";
std::cerr << "Unexpected error." << std::endl;
} }
else else
{ {
std::cerr << "Unexpected catch. This should not happen." << std::endl; std::cerr << "Unexpected catch. This should not happen." << std::endl;
} }
google::ShutDownCommandLineFlags(); google::ShutDownCommandLineFlags();
std::cout << "GNSS-SDR program ended." << std::endl;
return 1; return 1;
} }

View File

@ -64,17 +64,15 @@ using google::LogMessage;
DECLARE_string(log_dir); DECLARE_string(log_dir);
#if UNIT_TESTING_MINIMAL #if UNIT_TESTING_MINIMAL
#include "unit-tests/arithmetic/matio_test.cc" #include "unit-tests/arithmetic/matio_test.cc"
#if EXTRA_TESTS #if EXTRA_TESTS
#include "unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc"
#include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc" #include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc"
#if ENABLE_FPGA #if FPGA_BLOCKS_TEST
#include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc" #include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc"
#endif #endif // FPGA_BLOCKS_TEST
#include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc" #include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc"
#endif #endif // EXTRA_TESTS
#else #else
@ -160,12 +158,15 @@ DECLARE_string(log_dir);
#include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_kf_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_kf_tracking_test.cc"
#include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc"
#include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc" #include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc"
#if ENABLE_FPGA #if FPGA_BLOCKS_TEST
#include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc" #include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc"
#endif #endif // FPGA_BLOCKS_TEST
#include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc" #include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc"
#if FPGA_BLOCKS_TEST
#include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc"
#endif // FPGA_BLOCKS_TEST
#include "unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc" #include "unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc"
#endif #endif // EXTRA_TESTS
#endif // UNIT_TESTING_MINIMAL #endif // UNIT_TESTING_MINIMAL

View File

@ -94,7 +94,7 @@ DEFINE_bool(acq_test_dump, false, "Dump the results of an acquisition block into
// ######## GNURADIO BLOCK MESSAGE RECEVER ######### // ######## GNURADIO BLOCK MESSAGE RECEVER #########
class AcqPerfTest_msg_rx; class AcqPerfTest_msg_rx;
typedef boost::shared_ptr<AcqPerfTest_msg_rx> AcqPerfTest_msg_rx_sptr; using AcqPerfTest_msg_rx_sptr = boost::shared_ptr<AcqPerfTest_msg_rx>;
AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(Concurrent_Queue<int>& queue); AcqPerfTest_msg_rx_sptr AcqPerfTest_msg_rx_make(Concurrent_Queue<int>& queue);

View File

@ -57,7 +57,7 @@
// ######## GNURADIO BLOCK MESSAGE RECEVER ######### // ######## GNURADIO BLOCK MESSAGE RECEVER #########
class GlonassL1CaPcpsAcquisitionTest_msg_rx; class GlonassL1CaPcpsAcquisitionTest_msg_rx;
typedef boost::shared_ptr<GlonassL1CaPcpsAcquisitionTest_msg_rx> GlonassL1CaPcpsAcquisitionTest_msg_rx_sptr; using GlonassL1CaPcpsAcquisitionTest_msg_rx_sptr = boost::shared_ptr<GlonassL1CaPcpsAcquisitionTest_msg_rx>;
GlonassL1CaPcpsAcquisitionTest_msg_rx_sptr GlonassL1CaPcpsAcquisitionTest_msg_rx_make(); GlonassL1CaPcpsAcquisitionTest_msg_rx_sptr GlonassL1CaPcpsAcquisitionTest_msg_rx_make();

View File

@ -176,7 +176,7 @@ void thread_acquisition_send_rx_samples(gr::top_block_sptr top_block,
// ######## GNURADIO BLOCK MESSAGE RECEVER ######### // ######## GNURADIO BLOCK MESSAGE RECEVER #########
class GpsL1CaPcpsAcquisitionTestFpga_msg_rx; class GpsL1CaPcpsAcquisitionTestFpga_msg_rx;
typedef boost::shared_ptr<GpsL1CaPcpsAcquisitionTestFpga_msg_rx> GpsL1CaPcpsAcquisitionTest_msg_fpga_rx_sptr; using GpsL1CaPcpsAcquisitionTest_msg_fpga_rx_sptr = boost::shared_ptr<GpsL1CaPcpsAcquisitionTestFpga_msg_rx>;
GpsL1CaPcpsAcquisitionTest_msg_fpga_rx_sptr GpsL1CaPcpsAcquisitionTestFpga_msg_rx_make(); GpsL1CaPcpsAcquisitionTest_msg_fpga_rx_sptr GpsL1CaPcpsAcquisitionTestFpga_msg_rx_make();

View File

@ -63,7 +63,7 @@
// ######## GNURADIO BLOCK MESSAGE RECEVER ######### // ######## GNURADIO BLOCK MESSAGE RECEVER #########
class GpsL2MPcpsAcquisitionTest_msg_rx; class GpsL2MPcpsAcquisitionTest_msg_rx;
typedef boost::shared_ptr<GpsL2MPcpsAcquisitionTest_msg_rx> GpsL2MPcpsAcquisitionTest_msg_rx_sptr; using GpsL2MPcpsAcquisitionTest_msg_rx_sptr = boost::shared_ptr<GpsL2MPcpsAcquisitionTest_msg_rx>;
GpsL2MPcpsAcquisitionTest_msg_rx_sptr GpsL2MPcpsAcquisitionTest_msg_rx_make(); GpsL2MPcpsAcquisitionTest_msg_rx_sptr GpsL2MPcpsAcquisitionTest_msg_rx_make();

View File

@ -91,7 +91,7 @@
// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES ######### // ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES #########
class HybridObservablesTest_msg_rx; class HybridObservablesTest_msg_rx;
typedef boost::shared_ptr<HybridObservablesTest_msg_rx> HybridObservablesTest_msg_rx_sptr; using HybridObservablesTest_msg_rx_sptr = boost::shared_ptr<HybridObservablesTest_msg_rx>;
HybridObservablesTest_msg_rx_sptr HybridObservablesTest_msg_rx_make(); HybridObservablesTest_msg_rx_sptr HybridObservablesTest_msg_rx_make();
@ -142,7 +142,7 @@ HybridObservablesTest_msg_rx::~HybridObservablesTest_msg_rx() = default;
// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TLM MESSAGES ######### // ######## GNURADIO BLOCK MESSAGE RECEVER FOR TLM MESSAGES #########
class HybridObservablesTest_tlm_msg_rx; class HybridObservablesTest_tlm_msg_rx;
typedef boost::shared_ptr<HybridObservablesTest_tlm_msg_rx> HybridObservablesTest_tlm_msg_rx_sptr; using HybridObservablesTest_tlm_msg_rx_sptr = boost::shared_ptr<HybridObservablesTest_tlm_msg_rx>;
HybridObservablesTest_tlm_msg_rx_sptr HybridObservablesTest_tlm_msg_rx_make(); HybridObservablesTest_tlm_msg_rx_sptr HybridObservablesTest_tlm_msg_rx_make();

View File

@ -67,7 +67,7 @@
// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES ######### // ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES #########
class GpsL1CADllPllTelemetryDecoderTest_msg_rx; class GpsL1CADllPllTelemetryDecoderTest_msg_rx;
typedef boost::shared_ptr<GpsL1CADllPllTelemetryDecoderTest_msg_rx> GpsL1CADllPllTelemetryDecoderTest_msg_rx_sptr; using GpsL1CADllPllTelemetryDecoderTest_msg_rx_sptr = boost::shared_ptr<GpsL1CADllPllTelemetryDecoderTest_msg_rx>;
GpsL1CADllPllTelemetryDecoderTest_msg_rx_sptr GpsL1CADllPllTelemetryDecoderTest_msg_rx_make(); GpsL1CADllPllTelemetryDecoderTest_msg_rx_sptr GpsL1CADllPllTelemetryDecoderTest_msg_rx_make();
@ -118,7 +118,7 @@ GpsL1CADllPllTelemetryDecoderTest_msg_rx::~GpsL1CADllPllTelemetryDecoderTest_msg
// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TLM MESSAGES ######### // ######## GNURADIO BLOCK MESSAGE RECEVER FOR TLM MESSAGES #########
class GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx; class GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx;
typedef boost::shared_ptr<GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx> GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx_sptr; using GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx_sptr = boost::shared_ptr<GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx>;
GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx_sptr GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx_make(); GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx_sptr GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx_make();

View File

@ -63,7 +63,7 @@
// ######## GNURADIO BLOCK MESSAGE RECEVER ######### // ######## GNURADIO BLOCK MESSAGE RECEVER #########
class GpsL1CADllPllTrackingTest_msg_rx; class GpsL1CADllPllTrackingTest_msg_rx;
typedef boost::shared_ptr<GpsL1CADllPllTrackingTest_msg_rx> GpsL1CADllPllTrackingTest_msg_rx_sptr; using GpsL1CADllPllTrackingTest_msg_rx_sptr = boost::shared_ptr<GpsL1CADllPllTrackingTest_msg_rx>;
GpsL1CADllPllTrackingTest_msg_rx_sptr GpsL1CADllPllTrackingTest_msg_rx_make(); GpsL1CADllPllTrackingTest_msg_rx_sptr GpsL1CADllPllTrackingTest_msg_rx_make();

View File

@ -65,7 +65,7 @@ DEFINE_bool(plot_gps_l1_kf_tracking_test, false, "Plots results of GpsL1CAKfTrac
// ######## GNURADIO BLOCK MESSAGE RECEVER ######### // ######## GNURADIO BLOCK MESSAGE RECEVER #########
class GpsL1CAKfTrackingTest_msg_rx; class GpsL1CAKfTrackingTest_msg_rx;
typedef boost::shared_ptr<GpsL1CAKfTrackingTest_msg_rx> GpsL1CAKfTrackingTest_msg_rx_sptr; using GpsL1CAKfTrackingTest_msg_rx_sptr = boost::shared_ptr<GpsL1CAKfTrackingTest_msg_rx>;
GpsL1CAKfTrackingTest_msg_rx_sptr GpsL1CAKfTrackingTest_msg_rx_make(); GpsL1CAKfTrackingTest_msg_rx_sptr GpsL1CAKfTrackingTest_msg_rx_make();

View File

@ -57,7 +57,7 @@
// ######## GNURADIO BLOCK MESSAGE RECEVER ######### // ######## GNURADIO BLOCK MESSAGE RECEVER #########
class GpsL2MDllPllTrackingTest_msg_rx; class GpsL2MDllPllTrackingTest_msg_rx;
typedef boost::shared_ptr<GpsL2MDllPllTrackingTest_msg_rx> GpsL2MDllPllTrackingTest_msg_rx_sptr; using GpsL2MDllPllTrackingTest_msg_rx_sptr = boost::shared_ptr<GpsL2MDllPllTrackingTest_msg_rx>;
GpsL2MDllPllTrackingTest_msg_rx_sptr GpsL2MDllPllTrackingTest_msg_rx_make(); GpsL2MDllPllTrackingTest_msg_rx_sptr GpsL2MDllPllTrackingTest_msg_rx_make();

View File

@ -79,7 +79,7 @@
// ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER ######### // ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER #########
class TrackingPullInTest_msg_rx; class TrackingPullInTest_msg_rx;
typedef boost::shared_ptr<TrackingPullInTest_msg_rx> TrackingPullInTest_msg_rx_sptr; using TrackingPullInTest_msg_rx_sptr = boost::shared_ptr<TrackingPullInTest_msg_rx>;
TrackingPullInTest_msg_rx_sptr TrackingPullInTest_msg_rx_make(); TrackingPullInTest_msg_rx_sptr TrackingPullInTest_msg_rx_make();