diff --git a/CMakeLists.txt b/CMakeLists.txt
index 789a19974..22ad70e01 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -51,6 +51,7 @@ option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal
option(ENABLE_GN3S "Enable the use of the GN3S dongle as signal source (experimental)" OFF)
option(ENABLE_PLUTOSDR "Enable the use of ADALM-PLUTO Evaluation Boards (Analog Devices Inc.), requires gr-iio" OFF)
option(ENABLE_FMCOMMS2 "Enable the use of FMCOMMS4-EBZ + ZedBoard hardware, requires gr-iio" OFF)
+option(ENABLE_AD9361 "Enable the use of AD9361 directo to FPGA hardware, requires gr-iio" OFF)
# Performance analysis tools
option(ENABLE_GPERFTOOLS "Enable linking to Gperftools libraries (tcmalloc and profiler)" OFF)
diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc
index c1a037c11..d9ef75ae3 100644
--- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc
+++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc
@@ -1,14 +1,17 @@
/*!
* \file gps_l1_ca_pcps_acquisition_fpga.cc
- * \brief Adapts a PCPS acquisition block to an FPGA Acquisition Interface for
- * GPS L1 C/A signals. This file is based on the file gps_l1_ca_pcps_acquisition.cc
+ * \brief Adapts a PCPS acquisition block to an FPGA AcquisitionInterface
+ * for GPS L1 C/A signals
* \authors
- * - Marc Majoral, 2017. mmajoral(at)cttc.cat
+ *
- Marc Majoral, 2018. mmajoral(at)cttc.es
+ *
- Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Luis Esteve, 2012. luis(at)epsilon-formacion.com
+ *
- Marc Molina, 2013. marc.molina.pena(at)gmail.com
*
*
* -------------------------------------------------------------------------
*
- * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
+ * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@@ -31,13 +34,17 @@
* -------------------------------------------------------------------------
*/
-#include "gps_l1_ca_pcps_acquisition_fpga.h"
-#include
-#include
-#include
-#include "GPS_L1_CA.h"
#include "configuration_interface.h"
#include "gnss_sdr_flags.h"
+#include "gps_l1_ca_pcps_acquisition_fpga.h"
+#include "gps_sdr_signal_processing.h"
+#include "GPS_L1_CA.h"
+#include
+#include
+#include
+
+
+#define NUM_PRNs 32
using google::LogMessage;
@@ -45,87 +52,90 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
{
- unsigned int code_length;
- bool bit_transition_flag;
- bool use_CFAR_algorithm_flag;
- unsigned int sampled_ms;
- long fs_in;
- long ifreq;
- bool dump;
- std::string dump_filename;
- unsigned int nsamples_total;
- unsigned int select_queue_Fpga;
- std::string device_name;
-
+ pcpsconf_fpga_t acq_parameters;
configuration_ = configuration;
-
- std::string default_item_type = "cshort";
- std::string default_dump_filename = "./data/acquisition.dat";
+ std::string default_item_type = "gr_complex";
DLOG(INFO) << "role " << role;
- item_type_ = configuration_->property(role + ".item_type", default_item_type);
-
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
- fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
- ifreq = configuration_->property(role + ".if", 0);
- dump = configuration_->property(role + ".dump", false);
+ long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
+ acq_parameters.fs_in = fs_in;
+ long ifreq = configuration_->property(role + ".if", 0);
+ acq_parameters.freq = ifreq;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
- sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
-
- // note : the FPGA is implemented according to bit transition flag = 0. Setting bit transition flag to 1 has no effect.
- bit_transition_flag = configuration_->property(role + ".bit_transition_flag", false);
-
- // note : the FPGA is implemented according to use_CFAR_algorithm = 0. Setting use_CFAR_algorithm to 1 has no effect.
- use_CFAR_algorithm_flag = configuration_->property(role + ".use_CFAR_algorithm", false);
-
- // note : the FPGA does not use the max_dwells variable.
- max_dwells_ = configuration_->property(role + ".max_dwells", 1);
-
- dump_filename = configuration_->property(role + ".dump_filename", default_dump_filename);
-
- //--- Find number of samples per spreading code -------------------------
- code_length = round(
- fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
-
- // code length has the same value as d_fft_size
- float nbits;
- nbits = ceilf(log2f(code_length));
- nsamples_total = pow(2, nbits);
-
- //vector_length_ = code_length_ * sampled_ms_;
- vector_length_ = nsamples_total * sampled_ms;
-
- // if( bit_transition_flag_ )
- // {
- // vector_length_ *= 2;
- // }
-
- select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
+ acq_parameters.doppler_max = doppler_max_;
+ unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
+ acq_parameters.sampled_ms = sampled_ms;
+ unsigned int code_length = static_cast(std::round(static_cast(fs_in) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)));
+ // The FPGA can only use FFT lengths that are a power of two.
+ float nbits = ceilf(log2f((float)code_length));
+ unsigned int nsamples_total = pow(2, nbits);
+ unsigned int vector_length = nsamples_total * sampled_ms;
+ unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
+ acq_parameters.select_queue_Fpga = select_queue_Fpga;
std::string default_device_name = "/dev/uio0";
- 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.samples_per_ms = nsamples_total;
+ acq_parameters.samples_per_code = nsamples_total;
- if (item_type_.compare("cshort") == 0)
+ // compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
+ // a channel is assigned)
+
+ gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT
+ // allocate memory to compute all the PRNs and compute all the possible codes
+ std::complex* code = new std::complex[nsamples_total]; // buffer for the local code
+ gr_complex* fft_codes_padded = static_cast(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
+ d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32
+ float max; // temporary maxima search
+
+ for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
{
- item_size_ = sizeof(lv_16sc_t);
- gps_acquisition_fpga_sc_ = gps_pcps_make_acquisition_fpga_sc(
- sampled_ms, max_dwells_, doppler_max_, ifreq, fs_in,
- code_length, code_length, vector_length_, nsamples_total,
- bit_transition_flag, use_CFAR_algorithm_flag,
- select_queue_Fpga, device_name, dump, dump_filename);
- DLOG(INFO) << "acquisition("
- << gps_acquisition_fpga_sc_->unique_id() << ")";
- }
- else
- {
- LOG(WARNING) << "item_type configured to " << item_type_ << "but FPGA implementation only accepts cshort";
- throw std::invalid_argument("Wrong input_type configuration. Should be cshort");
+ gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code
+ // fill in zero padding
+ for (int s = code_length; s < nsamples_total; s++)
+ {
+ code[s] = 0;
+ }
+ int offset = 0;
+ memcpy(fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
+ fft_if->execute(); // Run the FFT of local code
+ volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
+ max = 0; // initialize maximum value
+ for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima
+ {
+ if (std::abs(fft_codes_padded[i].real()) > max)
+ {
+ max = std::abs(fft_codes_padded[i].real());
+ }
+ if (std::abs(fft_codes_padded[i].imag()) > max)
+ {
+ max = std::abs(fft_codes_padded[i].imag());
+ }
+ }
+ for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs
+ {
+ d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)),
+ static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max)));
+ }
}
+ //acq_parameters
+
+ acq_parameters.all_fft_codes = d_all_fft_codes_;
+
+ // temporary buffers that we can delete
+ delete[] code;
+ delete fft_if;
+ delete[] fft_codes_padded;
+
+ acquisition_fpga_ = pcps_make_acquisition(acq_parameters);
+ DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";
+
channel_ = 0;
- threshold_ = 0.0;
doppler_step_ = 0;
gnss_synchro_ = 0;
}
@@ -133,125 +143,93 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
GpsL1CaPcpsAcquisitionFpga::~GpsL1CaPcpsAcquisitionFpga()
{
+ delete[] d_all_fft_codes_;
}
void GpsL1CaPcpsAcquisitionFpga::set_channel(unsigned int channel)
{
channel_ = channel;
- gps_acquisition_fpga_sc_->set_channel(channel_);
+ acquisition_fpga_->set_channel(channel_);
}
void GpsL1CaPcpsAcquisitionFpga::set_threshold(float threshold)
{
- float pfa = configuration_->property(role_ + ".pfa", 0.0);
-
- if (pfa == 0.0)
- {
- threshold_ = threshold;
- }
- else
- {
- threshold_ = calculate_threshold(pfa);
- }
-
- DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_;
- gps_acquisition_fpga_sc_->set_threshold(threshold_);
+ DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold;
+ acquisition_fpga_->set_threshold(threshold);
}
void GpsL1CaPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max)
{
doppler_max_ = doppler_max;
- gps_acquisition_fpga_sc_->set_doppler_max(doppler_max_);
+ acquisition_fpga_->set_doppler_max(doppler_max_);
}
void GpsL1CaPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
{
doppler_step_ = doppler_step;
- gps_acquisition_fpga_sc_->set_doppler_step(doppler_step_);
+ acquisition_fpga_->set_doppler_step(doppler_step_);
}
void GpsL1CaPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
{
gnss_synchro_ = gnss_synchro;
- gps_acquisition_fpga_sc_->set_gnss_synchro(gnss_synchro_);
+ acquisition_fpga_->set_gnss_synchro(gnss_synchro_);
}
signed int GpsL1CaPcpsAcquisitionFpga::mag()
{
- return gps_acquisition_fpga_sc_->mag();
+ return acquisition_fpga_->mag();
}
void GpsL1CaPcpsAcquisitionFpga::init()
{
- gps_acquisition_fpga_sc_->init();
- set_local_code();
+ acquisition_fpga_->init();
}
void GpsL1CaPcpsAcquisitionFpga::set_local_code()
{
- gps_acquisition_fpga_sc_->set_local_code();
+ acquisition_fpga_->set_local_code();
}
void GpsL1CaPcpsAcquisitionFpga::reset()
{
- gps_acquisition_fpga_sc_->set_active(true);
+ acquisition_fpga_->set_active(true);
}
void GpsL1CaPcpsAcquisitionFpga::set_state(int state)
{
- gps_acquisition_fpga_sc_->set_state(state);
-}
-
-
-float GpsL1CaPcpsAcquisitionFpga::calculate_threshold(float pfa)
-{
- //Calculate the threshold
- unsigned int frequency_bins = 0;
- for (int doppler = static_cast(-doppler_max_); doppler <= static_cast(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(ncells);
- double val = pow(1.0 - pfa, exponent);
- double lambda = double(vector_length_);
- boost::math::exponential_distribution mydist(lambda);
- float threshold = static_cast(quantile(mydist, val));
-
- return threshold;
+ acquisition_fpga_->set_state(state);
}
void GpsL1CaPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block)
{
- //nothing to connect
+ // nothing to connect
}
void GpsL1CaPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block)
{
- //nothing to disconnect
+ // nothing to disconnect
}
gr::basic_block_sptr GpsL1CaPcpsAcquisitionFpga::get_left_block()
{
- return gps_acquisition_fpga_sc_;
+ return acquisition_fpga_;
}
gr::basic_block_sptr GpsL1CaPcpsAcquisitionFpga::get_right_block()
{
- return gps_acquisition_fpga_sc_;
+ return acquisition_fpga_;
}
diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h
index 2c8f9eed4..f070e8818 100644
--- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h
+++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h
@@ -1,14 +1,17 @@
/*!
* \file gps_l1_ca_pcps_acquisition_fpga.h
- * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
- * GPS L1 C/A signals. This file is based on the file gps_l1_ca_pcps_acquisition.h
+ * \brief Adapts a PCPS acquisition block that uses the FPGA to
+ * an AcquisitionInterface for GPS L1 C/A signals
* \authors
- * - Marc Majoral, 2017. mmajoral(at)cttc.cat
+ *
- Marc Majoral, 2018. mmajoral(at)cttc.es
+ *
- Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Luis Esteve, 2012. luis(at)epsilon-formacion.com
+ *
- Marc Molina, 2013. marc.molina.pena(at)gmail.com
*
*
* -------------------------------------------------------------------------
*
- * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
+ * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@@ -34,14 +37,11 @@
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FPGA_H_
#define GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FPGA_H_
-#include
-#include
-#include
-#include "gnss_synchro.h"
#include "acquisition_interface.h"
-#include "gps_pcps_acquisition_fpga_sc.h"
-#include "complex_byte_to_float_x2.h"
+#include "gnss_synchro.h"
+#include "pcps_acquisition_fpga.h"
#include
+#include
class ConfigurationInterface;
@@ -68,12 +68,13 @@ public:
*/
inline std::string implementation() override
{
- return "GPS_L1_CA_PCPS_Acquisition_Fpga";
+ return "GPS_L1_CA_PCPS_Acquisition";
}
inline size_t item_size() override
{
- return item_size_;
+ size_t item_size = sizeof(lv_16sc_t);
+ return item_size;
}
void connect(gr::top_block_sptr top_block) override;
@@ -135,21 +136,15 @@ public:
private:
ConfigurationInterface* configuration_;
- gps_pcps_acquisition_fpga_sc_sptr gps_acquisition_fpga_sc_;
- size_t item_size_;
- std::string item_type_;
- unsigned int vector_length_;
+ pcps_acquisition_fpga_sptr acquisition_fpga_;
unsigned int channel_;
- float threshold_;
unsigned int doppler_max_;
unsigned int doppler_step_;
- unsigned int max_dwells_;
Gnss_Synchro* gnss_synchro_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
-
- float calculate_threshold(float pfa);
+ lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts
};
-#endif /* GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_H_ */
+#endif /* GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FPGA_H_ */
diff --git a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt
index ca02bb952..9bfd4fc73 100644
--- a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt
+++ b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt
@@ -29,7 +29,7 @@ set(ACQ_GR_BLOCKS_SOURCES
)
if(ENABLE_FPGA)
- set(ACQ_GR_BLOCKS_SOURCES ${ACQ_GR_BLOCKS_SOURCES} gps_pcps_acquisition_fpga_sc.cc)
+ set(ACQ_GR_BLOCKS_SOURCES ${ACQ_GR_BLOCKS_SOURCES} pcps_acquisition_fpga.cc)
endif(ENABLE_FPGA)
if(OPENCL_FOUND)
diff --git a/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.cc b/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.cc
deleted file mode 100644
index d0f2baaf1..000000000
--- a/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.cc
+++ /dev/null
@@ -1,315 +0,0 @@
-/*!
- * \file gps_pcps_acquisition_fpga_sc.cc
- * \brief This class implements a Parallel Code Phase Search Acquisition in the FPGA.
- * This file is based on the file gps_pcps_acquisition_sc.cc
- * \authors
- * - Marc Majoral, 2017. mmajoral(at)cttc.cat
- *
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#include "gps_pcps_acquisition_fpga_sc.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include "control_message_factory.h"
-#include "GPS_L1_CA.h" //GPS_TWO_PI
-using google::LogMessage;
-
-void wait3(int seconds)
-{
- boost::this_thread::sleep_for(boost::chrono::seconds{seconds});
-}
-
-
-gps_pcps_acquisition_fpga_sc_sptr gps_pcps_make_acquisition_fpga_sc(
- unsigned int sampled_ms, unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in, int samples_per_ms,
- int samples_per_code, int vector_length, unsigned int nsamples_total,
- bool bit_transition_flag, bool use_CFAR_algorithm_flag,
- unsigned int select_queue_Fpga, std::string device_name, bool dump,
- std::string dump_filename)
-{
- return gps_pcps_acquisition_fpga_sc_sptr(
- new gps_pcps_acquisition_fpga_sc(sampled_ms, max_dwells,
- doppler_max, freq, fs_in, samples_per_ms, samples_per_code,
- vector_length, nsamples_total, bit_transition_flag,
- use_CFAR_algorithm_flag, select_queue_Fpga, device_name,
- dump, dump_filename));
-}
-
-
-gps_pcps_acquisition_fpga_sc::gps_pcps_acquisition_fpga_sc(
- unsigned int sampled_ms, unsigned int max_dwells,
- unsigned int doppler_max, long freq, long fs_in, int samples_per_ms,
- int samples_per_code, int vector_length, unsigned int nsamples_total,
- bool bit_transition_flag, bool use_CFAR_algorithm_flag,
- unsigned int select_queue_Fpga, std::string device_name, bool dump,
- std::string dump_filename) : gr::block("pcps_acquisition_fpga_sc",
- gr::io_signature::make(0, 0, sizeof(lv_16sc_t)),
- gr::io_signature::make(0, 0, 0))
-{
- this->message_port_register_out(pmt::mp("events"));
- d_sample_counter = 0; // SAMPLE COUNTER
- d_active = false;
- d_state = 0;
- d_samples_per_code = samples_per_code;
- d_max_dwells = max_dwells; // Note : d_max_dwells is not used in the FPGA implementation
- d_well_count = 0;
- d_doppler_max = doppler_max;
- d_fft_size = sampled_ms * samples_per_ms;
- d_mag = 0;
- d_num_doppler_bins = 0;
- d_bit_transition_flag = bit_transition_flag; // Note : bit transition flag is ignored and assumed 0 in the FPGA implementation
- d_use_CFAR_algorithm_flag = use_CFAR_algorithm_flag; // Note : user CFAR algorithm flag is ignored and assumed 0 in the FPGA implementation
- d_threshold = 0.0;
- d_doppler_step = 250;
- d_channel = 0;
-
- // For dumping samples into a file
- d_dump = dump;
- d_dump_filename = dump_filename;
-
- d_gnss_synchro = 0;
-
- // instantiate HW accelerator class
- acquisition_fpga_8sc = std::make_shared(device_name, vector_length, d_fft_size, nsamples_total, fs_in, freq, sampled_ms, select_queue_Fpga);
-}
-
-
-gps_pcps_acquisition_fpga_sc::~gps_pcps_acquisition_fpga_sc()
-{
- if (d_dump)
- {
- d_dump_file.close();
- }
-
- acquisition_fpga_8sc->free();
-}
-
-
-void gps_pcps_acquisition_fpga_sc::set_local_code()
-{
- acquisition_fpga_8sc->set_local_code(d_gnss_synchro->PRN);
-}
-
-
-void gps_pcps_acquisition_fpga_sc::init()
-{
- d_gnss_synchro->Flag_valid_acquisition = false;
- d_gnss_synchro->Flag_valid_symbol_output = false;
- d_gnss_synchro->Flag_valid_pseudorange = false;
- d_gnss_synchro->Flag_valid_word = false;
- d_gnss_synchro->Acq_delay_samples = 0.0;
- d_gnss_synchro->Acq_doppler_hz = 0.0;
- d_gnss_synchro->Acq_samplestamp_samples = 0;
- d_mag = 0.0;
-
- d_num_doppler_bins = ceil(
- static_cast(static_cast(d_doppler_max) - static_cast(-d_doppler_max)) / static_cast(d_doppler_step));
-
- acquisition_fpga_8sc->open_device();
-
- acquisition_fpga_8sc->init();
-}
-
-
-void gps_pcps_acquisition_fpga_sc::set_state(int state)
-{
- d_state = state;
- if (d_state == 1)
- {
- d_gnss_synchro->Acq_delay_samples = 0.0;
- d_gnss_synchro->Acq_doppler_hz = 0.0;
- d_gnss_synchro->Acq_samplestamp_samples = 0;
- d_well_count = 0;
- d_mag = 0.0;
- }
- else if (d_state == 0)
- {
- }
- else
- {
- LOG(ERROR) << "State can only be set to 0 or 1";
- }
-}
-
-
-void gps_pcps_acquisition_fpga_sc::set_active(bool active)
-{
- float temp_peak_to_noise_level = 0.0;
- float peak_to_noise_level = 0.0;
- float input_power;
- float test_statistics = 0.0;
- acquisition_fpga_8sc->block_samples(); // block the samples to run the acquisition this is only necessary for the tests
-
- d_active = active;
-
- int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
-
- d_state = 1;
-
- // initialize acquisition algorithm
- int doppler;
- uint32_t indext = 0;
- float magt = 0.0;
- //int effective_fft_size = ( d_bit_transition_flag ? d_fft_size/2 : d_fft_size );
- int effective_fft_size = d_fft_size;
- //float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size);
-
- d_mag = 0.0;
-
- unsigned int initial_sample;
-
- d_well_count++;
-
- DLOG(INFO) << "Channel: " << d_channel
- << " , doing acquisition of satellite: " << d_gnss_synchro->System
- << " " << d_gnss_synchro->PRN << " ,sample stamp: "
- << d_sample_counter << ", threshold: "
- << ", threshold: "
- << d_threshold << ", doppler_max: " << d_doppler_max
- << ", doppler_step: " << d_doppler_step;
-
- // Doppler frequency search loop
- for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins;
- doppler_index++)
- {
- doppler = -static_cast(d_doppler_max) + d_doppler_step * doppler_index;
-
- acquisition_fpga_8sc->set_phase_step(doppler_index);
- acquisition_fpga_8sc->run_acquisition(); // runs acquisition and waits until it is finished
-
- acquisition_fpga_8sc->read_acquisition_results(&indext, &magt,
- &initial_sample, &input_power);
-
- d_sample_counter = initial_sample;
-
- temp_peak_to_noise_level = static_cast(magt) / static_cast(input_power);
- if (peak_to_noise_level < temp_peak_to_noise_level)
- {
- peak_to_noise_level = temp_peak_to_noise_level;
- d_mag = magt;
-
- input_power = (input_power - d_mag) / (effective_fft_size - 1);
-
- d_gnss_synchro->Acq_delay_samples =
- static_cast(indext % d_samples_per_code);
- d_gnss_synchro->Acq_doppler_hz =
- static_cast(doppler);
- d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
- test_statistics = d_mag / input_power;
- }
-
- // Record results to file if required
- if (d_dump)
- {
- std::stringstream filename;
- //std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write
- filename.str("");
-
- boost::filesystem::path p = d_dump_filename;
- filename << p.parent_path().string()
- << boost::filesystem::path::preferred_separator
- << p.stem().string() << "_"
- << d_gnss_synchro->System << "_"
- << d_gnss_synchro->Signal << "_sat_"
- << d_gnss_synchro->PRN << "_doppler_" << doppler
- << p.extension().string();
-
- DLOG(INFO) << "Writing ACQ out to " << filename.str();
-
- d_dump_file.open(filename.str().c_str(),
- std::ios::out | std::ios::binary);
- d_dump_file.close();
- }
- }
-
- if (test_statistics > d_threshold)
- {
- d_state = 2; // Positive acquisition
-
- // 6.1- Declare positive acquisition using a message port
- DLOG(INFO) << "positive acquisition";
- DLOG(INFO) << "satellite " << d_gnss_synchro->System << " "
- << d_gnss_synchro->PRN;
- DLOG(INFO) << "sample_stamp " << d_sample_counter;
- DLOG(INFO) << "test statistics value " << test_statistics;
- DLOG(INFO) << "test statistics threshold " << d_threshold;
- DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
- DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
- DLOG(INFO) << "magnitude " << d_mag;
- DLOG(INFO) << "input signal power " << input_power;
-
- d_active = false;
- d_state = 0;
-
- acquisition_message = 1;
- this->message_port_pub(pmt::mp("events"),
- pmt::from_long(acquisition_message));
- }
- else
- {
- d_state = 3; // Negative acquisition
-
- // 6.2- Declare negative acquisition using a message port
- DLOG(INFO) << "negative acquisition";
- DLOG(INFO) << "satellite " << d_gnss_synchro->System << " "
- << d_gnss_synchro->PRN;
- DLOG(INFO) << "sample_stamp " << d_sample_counter;
- DLOG(INFO) << "test statistics value " << test_statistics;
- DLOG(INFO) << "test statistics threshold " << d_threshold;
- DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
- DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
- DLOG(INFO) << "magnitude " << d_mag;
- DLOG(INFO) << "input signal power " << input_power;
-
- d_active = false;
- d_state = 0;
-
- acquisition_message = 2;
- this->message_port_pub(pmt::mp("events"),
- pmt::from_long(acquisition_message));
- }
-
- acquisition_fpga_8sc->unblock_samples();
-
- acquisition_fpga_8sc->close_device();
-
- DLOG(INFO) << "Done. Consumed 1 item.";
-}
-
-
-int gps_pcps_acquisition_fpga_sc::general_work(int noutput_items,
- gr_vector_int &ninput_items, gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items __attribute__((unused)))
-{
- // general work not used with the acquisition
- return noutput_items;
-}
diff --git a/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.h b/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.h
deleted file mode 100644
index c5de39c69..000000000
--- a/src/algorithms/acquisition/gnuradio_blocks/gps_pcps_acquisition_fpga_sc.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*!
- * \file gps_pcps_acquisition_fpga_sc.h
- * \brief This class implements a Parallel Code Phase Search Acquisition in the FPGA.
- * This file is based on the file gps_pcps_acquisition_sc.h
- *
- * Acquisition strategy (Kay Borre book + CFAR threshold).
- *
- * - Compute the input signal power estimation
- *
- Doppler serial search loop
- *
- Perform the FFT-based circular convolution (parallel time search)
- *
- Record the maximum peak and the associated synchronization parameters
- *
- Compute the test statistics and compare to the threshold
- *
- Declare positive or negative acquisition using a message port
- *
- *
- * 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
- * Approach", Birkhauser, 2007. pp 81-84
- *
- * \authors
- * - Marc Majoral, 2017. mmajoral(at)cttc.cat
- *
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#ifndef GNSS_SDR_PCPS_ACQUISITION_FPGA_SC_H_
-#define GNSS_SDR_PCPS_ACQUISITION_FPGA_SC_H_
-
-#include
-#include
-#include
-#include
-#include
-#include "gnss_synchro.h"
-#include "gps_fpga_acquisition_8sc.h"
-
-class gps_pcps_acquisition_fpga_sc;
-
-typedef boost::shared_ptr gps_pcps_acquisition_fpga_sc_sptr;
-
-gps_pcps_acquisition_fpga_sc_sptr
-gps_pcps_make_acquisition_fpga_sc(unsigned int sampled_ms,
- unsigned int max_dwells, unsigned int doppler_max, long freq,
- long fs_in, int samples_per_ms, int samples_per_code,
- int vector_length_, unsigned int nsamples_total_,
- bool bit_transition_flag, bool use_CFAR_algorithm_flag,
- unsigned int select_queue_Fpga, std::string device_name, bool dump,
- std::string dump_filename);
-
-/*!
- * \brief This class implements a Parallel Code Phase Search Acquisition.
- *
- * Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver",
- * Algorithm 1, for a pseudocode description of this implementation.
- */
-class gps_pcps_acquisition_fpga_sc : public gr::block
-{
-private:
- friend gps_pcps_acquisition_fpga_sc_sptr
- gps_pcps_make_acquisition_fpga_sc(unsigned int sampled_ms,
- unsigned int max_dwells, unsigned int doppler_max, long freq,
- long fs_in, int samples_per_ms, int samples_per_code,
- int vector_length, unsigned int nsamples_total,
- bool bit_transition_flag, bool use_CFAR_algorithm_flag,
- unsigned int select_queue_Fpga, std::string device_name, bool dump,
- std::string dump_filename);
-
- gps_pcps_acquisition_fpga_sc(unsigned int sampled_ms,
- unsigned int max_dwells, unsigned int doppler_max, long freq,
- long fs_in, int samples_per_ms, int samples_per_code,
- int vector_length, unsigned int nsamples_total,
- bool bit_transition_flag, bool use_CFAR_algorithm_flag,
- unsigned int select_queue_Fpga, std::string device_name, bool dump,
- std::string dump_filename);
-
- int d_samples_per_code;
- float d_threshold;
- unsigned int d_doppler_max;
- unsigned int d_doppler_step;
- unsigned int d_max_dwells;
- unsigned int d_well_count;
- unsigned int d_fft_size;
- unsigned long int d_sample_counter;
- unsigned int d_num_doppler_bins;
-
- Gnss_Synchro *d_gnss_synchro;
- float d_mag;
- bool d_bit_transition_flag;
- bool d_use_CFAR_algorithm_flag;
- std::ofstream d_dump_file;
- bool d_active;
- int d_state;
- bool d_dump;
- unsigned int d_channel;
- std::string d_dump_filename;
-
- std::shared_ptr acquisition_fpga_8sc;
-
-public:
- /*!
- * \brief Default destructor.
- */
- ~gps_pcps_acquisition_fpga_sc();
-
- /*!
- * \brief Set acquisition/tracking common Gnss_Synchro object pointer
- * to exchange synchronization data between acquisition and tracking blocks.
- * \param p_gnss_synchro Satellite information shared by the processing blocks.
- */
- inline void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro)
- {
- d_gnss_synchro = p_gnss_synchro;
- }
-
- /*!
- * \brief Returns the maximum peak of grid search.
- */
- inline unsigned int mag() const
- {
- return d_mag;
- }
-
- /*!
- * \brief Initializes acquisition algorithm.
- */
- void init();
-
- /*!
- * \brief Sets local code for PCPS acquisition algorithm.
- * \param code - Pointer to the PRN code.
- */
- void set_local_code();
-
- /*!
- * \brief Starts acquisition algorithm, turning from standby mode to
- * active mode
- * \param active - bool that activates/deactivates the block.
- */
- void set_active(bool active);
-
- /*!
- * \brief If set to 1, ensures that acquisition starts at the
- * first available sample.
- * \param state - int=1 forces start of acquisition
- */
- void set_state(int state);
-
- /*!
- * \brief Set acquisition channel unique ID
- * \param channel - receiver channel.
- */
- inline void set_channel(unsigned int channel)
- {
- d_channel = channel;
- }
-
- /*!
- * \brief Set statistics threshold of PCPS algorithm.
- * \param threshold - Threshold for signal detection (check \ref Navitec2012,
- * Algorithm 1, for a definition of this threshold).
- */
- inline void set_threshold(float threshold)
- {
- d_threshold = threshold;
- }
-
- /*!
- * \brief Set maximum Doppler grid search
- * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
- */
- inline void set_doppler_max(unsigned int doppler_max)
- {
- d_doppler_max = doppler_max;
- acquisition_fpga_8sc->set_doppler_max(doppler_max);
- }
-
- /*!
- * \brief Set Doppler steps for the grid search
- * \param doppler_step - Frequency bin of the search grid [Hz].
- */
- inline void set_doppler_step(unsigned int doppler_step)
- {
- d_doppler_step = doppler_step;
- acquisition_fpga_8sc->set_doppler_step(doppler_step);
- }
-
- /*!
- * \brief Parallel Code Phase Search Acquisition signal processing.
- */
- int general_work(int noutput_items, gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif /* GNSS_SDR_PCPS_ACQUISITION_SC_H_*/
diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc
new file mode 100644
index 000000000..6a337925e
--- /dev/null
+++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc
@@ -0,0 +1,244 @@
+/*!
+ * \file pcps_acquisition_fpga.cc
+ * \brief This class implements a Parallel Code Phase Search Acquisition in 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
+ * - Marc Majoral, 2017. mmajoral(at)cttc.cat
+ *
- Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Luis Esteve, 2012. luis(at)epsilon-formacion.com
+ *
- Marc Molina, 2013. marc.molina.pena@gmail.com
+ *
- Cillian O'Driscoll, 2017. cillian(at)ieee.org
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+
+#include
+#include
+#include "pcps_acquisition_fpga.h"
+
+using google::LogMessage;
+
+pcps_acquisition_fpga_sptr pcps_make_acquisition(pcpsconf_fpga_t conf_)
+{
+ return pcps_acquisition_fpga_sptr(new pcps_acquisition_fpga(conf_));
+}
+
+
+pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_) : gr::block("pcps_acquisition_fpga",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(0, 0, 0))
+{
+ this->message_port_register_out(pmt::mp("events"));
+
+ acq_parameters = conf_;
+ d_sample_counter = 0; // SAMPLE COUNTER
+ d_active = false;
+ d_state = 0;
+ d_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms;
+ d_mag = 0;
+ d_input_power = 0.0;
+ d_num_doppler_bins = 0;
+ d_threshold = 0.0;
+ d_doppler_step = 0;
+ d_test_statistics = 0.0;
+ d_channel = 0;
+ d_gnss_synchro = 0;
+
+ acquisition_fpga = std::make_shared
+ (acq_parameters.device_name, d_fft_size, 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);
+
+}
+
+
+pcps_acquisition_fpga::~pcps_acquisition_fpga()
+{
+ acquisition_fpga->free();
+}
+
+
+void pcps_acquisition_fpga::set_local_code()
+{
+ acquisition_fpga->set_local_code(d_gnss_synchro->PRN);
+}
+
+
+void pcps_acquisition_fpga::init()
+{
+ d_gnss_synchro->Flag_valid_acquisition = false;
+ d_gnss_synchro->Flag_valid_symbol_output = false;
+ d_gnss_synchro->Flag_valid_pseudorange = false;
+ d_gnss_synchro->Flag_valid_word = false;
+ d_gnss_synchro->Acq_delay_samples = 0.0;
+ d_gnss_synchro->Acq_doppler_hz = 0.0;
+ d_gnss_synchro->Acq_samplestamp_samples = 0;
+ d_mag = 0.0;
+ d_input_power = 0.0;
+ d_num_doppler_bins = static_cast(std::ceil(static_cast(static_cast(acq_parameters.doppler_max) - static_cast(-acq_parameters.doppler_max)) / static_cast(d_doppler_step)));
+
+ acquisition_fpga->init();
+}
+
+
+void pcps_acquisition_fpga::set_state(int state)
+{
+ d_state = state;
+ if (d_state == 1)
+ {
+ d_gnss_synchro->Acq_delay_samples = 0.0;
+ d_gnss_synchro->Acq_doppler_hz = 0.0;
+ d_gnss_synchro->Acq_samplestamp_samples = 0;
+ //d_well_count = 0;
+ d_mag = 0.0;
+ d_input_power = 0.0;
+ d_test_statistics = 0.0;
+ d_active = true;
+ }
+ else if (d_state == 0)
+ {
+ }
+ else
+ {
+ LOG(ERROR) << "State can only be set to 0 or 1";
+ }
+}
+
+
+void pcps_acquisition_fpga::send_positive_acquisition()
+{
+ // 6.1- Declare positive acquisition using a message port
+ //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
+ DLOG(INFO) << "positive acquisition"
+ << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
+ << ", sample_stamp " << d_sample_counter
+ << ", test statistics value " << d_test_statistics
+ << ", test statistics threshold " << d_threshold
+ << ", code phase " << d_gnss_synchro->Acq_delay_samples
+ << ", doppler " << d_gnss_synchro->Acq_doppler_hz
+ << ", magnitude " << d_mag
+ << ", input signal power " << d_input_power;
+
+ this->message_port_pub(pmt::mp("events"), pmt::from_long(1));
+}
+
+
+void pcps_acquisition_fpga::send_negative_acquisition()
+{
+ // 6.2- Declare negative acquisition using a message port
+ //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
+ DLOG(INFO) << "negative acquisition"
+ << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
+ << ", sample_stamp " << d_sample_counter
+ << ", test statistics value " << d_test_statistics
+ << ", test statistics threshold " << d_threshold
+ << ", code phase " << d_gnss_synchro->Acq_delay_samples
+ << ", doppler " << d_gnss_synchro->Acq_doppler_hz
+ << ", magnitude " << d_mag
+ << ", input signal power " << d_input_power;
+
+ this->message_port_pub(pmt::mp("events"), pmt::from_long(2));
+}
+
+
+void pcps_acquisition_fpga::set_active(bool active)
+{
+ d_active = active;
+
+ // initialize acquisition algorithm
+ uint32_t indext = 0;
+ float magt = 0.0;
+ float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size);
+
+ d_input_power = 0.0;
+ d_mag = 0.0;
+
+ DLOG(INFO) << "Channel: " << d_channel
+ << " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN
+ << " ,sample stamp: " << d_sample_counter << ", threshold: "
+ << d_threshold << ", doppler_max: " << acq_parameters.doppler_max
+ << ", doppler_step: " << d_doppler_step
+ // no CFAR algorithm in the FPGA
+ << ", use_CFAR_algorithm_flag: false";
+
+ unsigned int initial_sample;
+ float input_power_all = 0.0;
+ float input_power_computed = 0.0;
+ for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
+ {
+ // doppler search steps
+ int doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
+
+ acquisition_fpga->set_phase_step(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_sample_counter = initial_sample;
+
+ if (d_mag < magt)
+ {
+ d_mag = magt;
+
+ 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(indext % acq_parameters.samples_per_code);
+ d_gnss_synchro->Acq_doppler_hz = static_cast(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
+ }
+
+ if (d_test_statistics > d_threshold)
+ {
+ d_active = false;
+ send_positive_acquisition();
+ d_state = 0; // Positive acquisition
+ }
+ else
+ {
+ d_state = 0;
+ d_active = false;
+ send_negative_acquisition();
+ }
+}
+
+
+int pcps_acquisition_fpga::general_work(int noutput_items __attribute__((unused)),
+ gr_vector_int& ninput_items, gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items __attribute__((unused)))
+{
+ // the general work is not used with the acquisition that uses the FPGA
+ return noutput_items;
+}
diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h
new file mode 100644
index 000000000..e758904e3
--- /dev/null
+++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h
@@ -0,0 +1,213 @@
+/*!
+ * \file pcps_acquisition_fpga.h
+ * \brief This class implements a Parallel Code Phase Search Acquisition in 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).
+ *
+ * - Compute the input signal power estimation
+ *
- Doppler serial search loop
+ *
- Perform the FFT-based circular convolution (parallel time search)
+ *
- Record the maximum peak and the associated synchronization parameters
+ *
- Compute the test statistics and compare to the threshold
+ *
- Declare positive or negative acquisition using a message queue
+ *
+ *
+ * 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
+ * Approach", Birkhauser, 2007. pp 81-84
+ *
+ * \authors
+ * - Marc Majoral, 2017. mmajoral(at)cttc.cat
+ *
- Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Luis Esteve, 2012. luis(at)epsilon-formacion.com
+ *
- Marc Molina, 2013. marc.molina.pena@gmail.com
+ *
- Cillian O'Driscoll, 2017. cillian(at)ieee.org
+ *
- Antonio Ramos, 2017. antonio.ramos@cttc.es
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef GNSS_SDR_PCPS_ACQUISITION_FPGA_H_
+#define GNSS_SDR_PCPS_ACQUISITION_FPGA_H_
+
+
+#include "fpga_acquisition.h"
+#include "gnss_synchro.h"
+#include
+
+typedef struct
+{
+ /* pcps acquisition configuration */
+ unsigned int sampled_ms;
+ unsigned int doppler_max;
+ long freq;
+ long fs_in;
+ int samples_per_ms;
+ int samples_per_code;
+ unsigned int select_queue_Fpga;
+ std::string device_name;
+ lv_16sc_t* all_fft_codes; // memory that contains all the code ffts
+
+} pcpsconf_fpga_t;
+
+class pcps_acquisition_fpga;
+
+typedef boost::shared_ptr pcps_acquisition_fpga_sptr;
+
+pcps_acquisition_fpga_sptr
+pcps_make_acquisition(pcpsconf_fpga_t conf_);
+
+/*!
+ * \brief This class implements a Parallel Code Phase Search Acquisition that uses the FPGA.
+ *
+ * Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver",
+ * Algorithm 1, for a pseudocode description of this implementation.
+ */
+class pcps_acquisition_fpga : public gr::block
+{
+private:
+ friend pcps_acquisition_fpga_sptr
+
+ pcps_make_acquisition(pcpsconf_fpga_t conf_);
+
+ pcps_acquisition_fpga(pcpsconf_fpga_t conf_);
+
+ void send_negative_acquisition();
+
+ void send_positive_acquisition();
+
+ pcpsconf_fpga_t acq_parameters;
+ bool d_active;
+ float d_threshold;
+ float d_mag;
+ float d_input_power;
+ float d_test_statistics;
+ int d_state;
+ unsigned int d_channel;
+ unsigned int d_doppler_step;
+ unsigned int d_fft_size;
+ unsigned int d_num_doppler_bins;
+ unsigned long int d_sample_counter;
+ Gnss_Synchro* d_gnss_synchro;
+ std::shared_ptr acquisition_fpga;
+
+public:
+ ~pcps_acquisition_fpga();
+
+ /*!
+ * \brief Set acquisition/tracking common Gnss_Synchro object pointer
+ * to exchange synchronization data between acquisition and tracking blocks.
+ * \param p_gnss_synchro Satellite information shared by the processing blocks.
+ */
+ inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
+ {
+ d_gnss_synchro = p_gnss_synchro;
+ }
+
+ /*!
+ * \brief Returns the maximum peak of grid search.
+ */
+ inline unsigned int mag() const
+ {
+ return d_mag;
+ }
+
+ /*!
+ * \brief Initializes acquisition algorithm.
+ */
+ void init();
+
+ /*!
+ * \brief Sets local code for PCPS acquisition algorithm.
+ * \param code - Pointer to the PRN code.
+ */
+ void set_local_code();
+
+ /*!
+ * \brief If set to 1, ensures that acquisition starts at the
+ * first available sample.
+ * \param state - int=1 forces start of acquisition
+ */
+ void set_state(int state);
+
+ /*!
+ * \brief Starts acquisition algorithm, turning from standby mode to
+ * active mode
+ * \param active - bool that activates/deactivates the block.
+ */
+ void set_active(bool active);
+
+ /*!
+ * \brief Set acquisition channel unique ID
+ * \param channel - receiver channel.
+ */
+ inline void set_channel(unsigned int channel)
+ {
+ d_channel = channel;
+ }
+
+ /*!
+ * \brief Set statistics threshold of PCPS algorithm.
+ * \param threshold - Threshold for signal detection (check \ref Navitec2012,
+ * Algorithm 1, for a definition of this threshold).
+ */
+ inline void set_threshold(float threshold)
+ {
+ d_threshold = threshold;
+ }
+
+ /*!
+ * \brief Set maximum Doppler grid search
+ * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
+ */
+ inline void set_doppler_max(unsigned int doppler_max)
+ {
+ acq_parameters.doppler_max = doppler_max;
+ acquisition_fpga->set_doppler_max(doppler_max);
+ }
+
+ /*!
+ * \brief Set Doppler steps for the grid search
+ * \param doppler_step - Frequency bin of the search grid [Hz].
+ */
+ inline void set_doppler_step(unsigned int doppler_step)
+ {
+ d_doppler_step = doppler_step;
+ acquisition_fpga->set_doppler_step(doppler_step);
+ }
+
+ /*!
+ * \brief Parallel Code Phase Search Acquisition signal processing.
+ */
+ int general_work(int noutput_items, gr_vector_int& ninput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items);
+};
+
+#endif /* GNSS_SDR_PCPS_ACQUISITION_FPGA_H_*/
diff --git a/src/algorithms/acquisition/libs/CMakeLists.txt b/src/algorithms/acquisition/libs/CMakeLists.txt
index 53feb9366..f4adf131c 100644
--- a/src/algorithms/acquisition/libs/CMakeLists.txt
+++ b/src/algorithms/acquisition/libs/CMakeLists.txt
@@ -18,7 +18,7 @@
set(ACQUISITION_LIB_SOURCES
- gps_fpga_acquisition_8sc.cc
+ fpga_acquisition.cc
)
include_directories(
diff --git a/src/algorithms/acquisition/libs/fpga_acquisition.cc b/src/algorithms/acquisition/libs/fpga_acquisition.cc
new file mode 100644
index 000000000..81995faab
--- /dev/null
+++ b/src/algorithms/acquisition/libs/fpga_acquisition.cc
@@ -0,0 +1,265 @@
+/*!
+ * \file fpga_acquisition.cc
+ * \brief High optimized FPGA vector correlator class
+ * \authors
+ * - Marc Majoral, 2018. mmajoral(at)cttc.cat
+ *
+ *
+ * Class that controls and executes a high optimized acquisition HW
+ * accelerator in the FPGA
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "fpga_acquisition.h"
+#include "GPS_L1_CA.h"
+#include "gps_sdr_signal_processing.h"
+#include
+#include // libraries used by the GIPO
+#include // libraries used by the GIPO
+
+
+#define PAGE_SIZE 0x10000 // default page size for the multicorrelator memory map
+#define MAX_PHASE_STEP_RAD 0.999999999534339 // 1 - pow(2,-31);
+#define RESET_ACQUISITION 2 // command to reset the multicorrelator
+#define LAUNCH_ACQUISITION 1 // command to launch the multicorrelator
+#define TEST_REG_SANITY_CHECK 0x55AA // value to check the presence of the test register (to detect the hw)
+#define LOCAL_CODE_CLEAR_MEM 0x10000000 // command to clear the internal memory of the multicorrelator
+#define MEM_LOCAL_CODE_WR_ENABLE 0x0C000000 // command to enable the ENA and WR pins of the internal memory of the multicorrelator
+#define POW_2_2 4 // 2^2 (used for the conversion of floating point numbers to integers)
+#define POW_2_29 536870912 // 2^29 (used for the conversion of floating point numbers to integers)
+#define SELECT_LSB 0x00FF // value to select the least significant byte
+#define SELECT_MSB 0XFF00 // value to select the most significant byte
+#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
+
+
+bool fpga_acquisition::init()
+{
+ // configure the acquisition with the main initialization values
+ fpga_acquisition::configure_acquisition();
+ return true;
+}
+
+
+bool fpga_acquisition::set_local_code(unsigned int PRN)
+{
+ // select the code with the chosen PRN
+ fpga_acquisition::fpga_configure_acquisition_local_code(
+ &d_all_fft_codes[d_nsamples_total * (PRN - 1)]);
+ return true;
+}
+
+
+fpga_acquisition::fpga_acquisition(std::string device_name,
+ unsigned int nsamples,
+ unsigned int doppler_max,
+ unsigned int nsamples_total, long fs_in, long freq,
+ unsigned int sampled_ms, unsigned select_queue,
+ lv_16sc_t *all_fft_codes)
+{
+ unsigned int vector_length = nsamples_total * sampled_ms;
+ // initial values
+ d_device_name = device_name;
+ d_freq = freq;
+ d_fs_in = fs_in;
+ d_vector_length = vector_length;
+ d_nsamples = nsamples; // number of samples not including padding
+ d_select_queue = select_queue;
+ d_nsamples_total = nsamples_total;
+ d_doppler_max = doppler_max;
+ d_doppler_step = 0;
+ d_fd = 0; // driver descriptor
+ d_map_base = nullptr; // driver memory map
+ d_all_fft_codes = all_fft_codes;
+
+ // open communication with HW accelerator
+ if ((d_fd = open(d_device_name.c_str(), O_RDWR | O_SYNC)) == -1)
+ {
+ LOG(WARNING) << "Cannot open deviceio" << d_device_name;
+ }
+ d_map_base = reinterpret_cast(mmap(NULL, PAGE_SIZE,
+ PROT_READ | PROT_WRITE, MAP_SHARED, d_fd, 0));
+
+ if (d_map_base == reinterpret_cast(-1))
+ {
+ LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory";
+ }
+
+ // sanity check : check test register
+ unsigned writeval = TEST_REG_SANITY_CHECK;
+ unsigned readval;
+ readval = fpga_acquisition::fpga_acquisition_test_register(writeval);
+ if (writeval != readval)
+ {
+ LOG(WARNING) << "Acquisition test register sanity check failed";
+ }
+ else
+ {
+ LOG(INFO) << "Acquisition test register sanity check success!";
+ }
+ fpga_acquisition::reset_acquisition();
+ DLOG(INFO) << "Acquisition FPGA class created";
+}
+
+
+fpga_acquisition::~fpga_acquisition()
+{
+ close_device();
+}
+
+
+bool fpga_acquisition::free()
+{
+ return true;
+}
+
+
+unsigned fpga_acquisition::fpga_acquisition_test_register(unsigned writeval)
+{
+ unsigned 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[])
+{
+ unsigned short local_code;
+ unsigned int k, tmp, tmp2;
+ unsigned int fft_data;
+ // clear memory address counter
+ d_map_base[4] = LOCAL_CODE_CLEAR_MEM;
+ // write local code
+ for (k = 0; k < d_vector_length; k++)
+ {
+ tmp = fft_local_code[k].real();
+ tmp2 = fft_local_code[k].imag();
+ local_code = (tmp & SELECT_LSB) | ((tmp2 * SHL_8_BITS) & SELECT_MSB); // put together the real part and the imaginary part
+ fft_data = MEM_LOCAL_CODE_WR_ENABLE | (local_code & SELECT_16_BITS);
+ d_map_base[4] = fft_data;
+ }
+}
+
+
+void fpga_acquisition::run_acquisition(void)
+{
+ // enable interrupts
+ int reenable = 1;
+ write(d_fd, reinterpret_cast(&reenable), sizeof(int));
+ // launch the acquisition process
+ d_map_base[6] = LAUNCH_ACQUISITION; // writing anything to reg 6 launches the acquisition process
+
+ int irq_count;
+ ssize_t nb;
+ // wait for interrupt
+ nb = read(d_fd, &irq_count, sizeof(irq_count));
+ if (nb != sizeof(irq_count))
+ {
+ printf("acquisition module Read failed to retrieve 4 bytes!\n");
+ printf("acquisition module Interrupt number %d\n", irq_count);
+ }
+}
+
+
+void fpga_acquisition::configure_acquisition()
+{
+ d_map_base[0] = d_select_queue;
+ d_map_base[1] = d_vector_length;
+ d_map_base[2] = d_nsamples;
+ d_map_base[5] = (int)log2((float)d_vector_length); // log2 FFTlength
+}
+
+
+void fpga_acquisition::set_phase_step(unsigned int doppler_index)
+{
+ float phase_step_rad_real;
+ float phase_step_rad_int_temp;
+ int32_t phase_step_rad_int;
+ int doppler = static_cast(-d_doppler_max) + d_doppler_step * doppler_index;
+ float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast(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)
+ if (phase_step_rad_real >= 1.0)
+ {
+ phase_step_rad_real = MAX_PHASE_STEP_RAD;
+ }
+ phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2
+ phase_step_rad_int = (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
+ d_map_base[3] = phase_step_rad_int;
+}
+
+
+void fpga_acquisition::read_acquisition_results(uint32_t *max_index,
+ float *max_magnitude, unsigned *initial_sample, float *power_sum)
+{
+ unsigned readval = 0;
+ readval = d_map_base[1];
+ *initial_sample = readval;
+ readval = d_map_base[2];
+ *max_magnitude = static_cast(readval);
+ readval = d_map_base[4];
+ *power_sum = static_cast(readval);
+ readval = d_map_base[3];
+ *max_index = readval;
+}
+
+
+void fpga_acquisition::block_samples()
+{
+ d_map_base[14] = 1; // block the samples
+}
+
+
+void fpga_acquisition::unblock_samples()
+{
+ d_map_base[14] = 0; // unblock the samples
+}
+
+
+void fpga_acquisition::close_device()
+{
+ unsigned *aux = const_cast(d_map_base);
+ if (munmap(static_cast(aux), PAGE_SIZE) == -1)
+ {
+ printf("Failed to unmap memory uio\n");
+ }
+ close(d_fd);
+}
+
+
+void fpga_acquisition::reset_acquisition(void)
+{
+ d_map_base[6] = RESET_ACQUISITION; // writing a 2 to d_map_base[6] resets the multicorrelator
+}
diff --git a/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.h b/src/algorithms/acquisition/libs/fpga_acquisition.h
similarity index 76%
rename from src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.h
rename to src/algorithms/acquisition/libs/fpga_acquisition.h
index 40f8f37f2..00641e1cd 100644
--- a/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.h
+++ b/src/algorithms/acquisition/libs/fpga_acquisition.h
@@ -1,12 +1,12 @@
/*!
- * \file fpga_acquisition_8sc.h
- * \brief High optimized FPGA vector correlator class for lv_16sc_t (short int complex).
+ * \file fpga_acquisition.h
+ * \brief High optimized FPGA vector correlator class
* \authors
- * - Marc Majoral, 2017. mmajoral(at)cttc.cat
+ *
- Marc Majoral, 2018. mmajoral(at)cttc.cat
*
*
- * Class that controls and executes a high optimized vector correlator
- * class in the FPGA
+ * Class that controls and executes a high optimized acquisition HW
+ * accelerator in the FPGA
*
* -------------------------------------------------------------------------
*
@@ -33,28 +33,28 @@
* -------------------------------------------------------------------------
*/
-#ifndef GNSS_SDR_FPGA_ACQUISITION_8SC_H_
-#define GNSS_SDR_FPGA_ACQUISITION_8SC_H_
+#ifndef GNSS_SDR_FPGA_ACQUISITION_H_
+#define GNSS_SDR_FPGA_ACQUISITION_H_
-#include
-
-#include
#include
+#include
/*!
* \brief Class that implements carrier wipe-off and correlators.
*/
-class gps_fpga_acquisition_8sc
+class fpga_acquisition
{
public:
- gps_fpga_acquisition_8sc(std::string device_name,
- unsigned int vector_length, unsigned int nsamples,
+ fpga_acquisition(std::string device_name,
+ unsigned int nsamples,
+ unsigned int doppler_max,
unsigned int nsamples_total, long fs_in, long freq,
- unsigned int sampled_ms, unsigned select_queue);
- ~gps_fpga_acquisition_8sc();
+ unsigned int sampled_ms, unsigned select_queue,
+ lv_16sc_t *all_fft_codes);
+ ~fpga_acquisition();
bool init();
bool set_local_code(
- unsigned int PRN); //int code_length_chips, const lv_16sc_t* local_code_in, float *shifts_chips);
+ unsigned int PRN);
bool free();
void run_acquisition(void);
void set_phase_step(unsigned int doppler_index);
@@ -62,8 +62,6 @@ public:
unsigned *initial_sample, float *power_sum);
void block_samples();
void unblock_samples();
- void open_device();
- void close_device();
/*!
* \brief Set maximum Doppler grid search
@@ -87,22 +85,23 @@ private:
long d_freq;
long d_fs_in;
gr::fft::fft_complex *d_fft_if; // function used to run the fft of the local codes
-
// data related to the hardware module and the driver
int d_fd; // driver descriptor
volatile unsigned *d_map_base; // driver memory map
lv_16sc_t *d_all_fft_codes; // memory that contains all the code ffts
- unsigned int d_vector_length; // number of samples including padding and number of ms
+ unsigned int d_vector_length; // number of samples incluing padding and number of ms
+ unsigned int d_nsamples_total; // number of samples including padding
unsigned int d_nsamples; // number of samples not including padding
unsigned int d_select_queue; // queue selection
std::string d_device_name; // HW device name
unsigned int d_doppler_max; // max doppler
unsigned int d_doppler_step; // doppler step
-
// FPGA private functions
unsigned fpga_acquisition_test_register(unsigned writeval);
void fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]);
void configure_acquisition();
+ void reset_acquisition(void);
+ void close_device();
};
-#endif /* GNSS_SDR_FPGA_MULTICORRELATOR_H_ */
+#endif /* GNSS_SDR_FPGA_ACQUISITION_H_ */
diff --git a/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.cc b/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.cc
deleted file mode 100644
index b1a855a11..000000000
--- a/src/algorithms/acquisition/libs/gps_fpga_acquisition_8sc.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-/*!
- * \file gps_fpga_acquisition_8sc.cc
- * \brief High optimized FPGA vector correlator class
- * \authors
- * - Marc Majoral, 2017. mmajoral(at)cttc.cat
- *
- *
- * Class that controls and executes a high optimized vector correlator
- * class in the FPGA
- *
- * -------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#include "gps_fpga_acquisition_8sc.h"
-#include "gps_sdr_signal_processing.h"
-#include "GPS_L1_CA.h"
-#include
-#include
-
-// allocate memory dynamically
-#include
-
-// libraries used by DMA test code and GIPO test code
-#include
-#include
-#include
-#include
-
-// libraries used by DMA test code
-#include
-#include
-#include
-
-// libraries used by GPIO test code
-#include
-#include
-#include
-
-// logging
-#include
-
-
-#define PAGE_SIZE 0x10000
-#define MAX_PHASE_STEP_RAD 0.999999999534339 // 1 - pow(2,-31);
-#define NUM_PRNs 32
-#define TEST_REGISTER_ACQ_WRITEVAL 0x55AA
-
-bool gps_fpga_acquisition_8sc::init()
-{
- // configure the acquisition with the main initialization values
- gps_fpga_acquisition_8sc::configure_acquisition();
- return true;
-}
-
-bool gps_fpga_acquisition_8sc::set_local_code(unsigned int PRN)
-{
- // select the code with the chosen PRN
- gps_fpga_acquisition_8sc::fpga_configure_acquisition_local_code(
- &d_all_fft_codes[d_vector_length * PRN]);
- return true;
-}
-
-gps_fpga_acquisition_8sc::gps_fpga_acquisition_8sc(std::string device_name,
- unsigned int vector_length, unsigned int nsamples,
- unsigned int nsamples_total, long fs_in, long freq,
- unsigned int sampled_ms, unsigned select_queue)
-{
- // initial values
- d_device_name = device_name;
- d_freq = freq;
- d_fs_in = fs_in;
- d_vector_length = vector_length;
- d_nsamples = nsamples; // number of samples not including padding
- d_select_queue = select_queue;
-
- d_doppler_max = 0;
- d_doppler_step = 0;
- d_fd = 0; // driver descriptor
- d_map_base = nullptr; // driver memory map
-
- // compute all the possible code ffts
-
- // Direct FFT
- d_fft_if = new gr::fft::fft_complex(vector_length, true);
-
- // allocate memory to compute all the PRNs
- // and compute all the possible codes
- std::complex* code = new std::complex[nsamples_total]; // buffer for the local code
- std::complex* code_total = new gr_complex[vector_length]; // buffer for the local code repeat every number of ms
-
- gr_complex* d_fft_codes_padded = static_cast(volk_gnsssdr_malloc(vector_length * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
-
- d_all_fft_codes = new lv_16sc_t[vector_length * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32
-
- float max; // temporary maxima search
-
- for (unsigned int PRN = 0; PRN < NUM_PRNs; PRN++)
- {
- gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code
-
- for (unsigned int i = 0; i < sampled_ms; i++)
- {
- memcpy(&(code_total[i * nsamples_total]), code, sizeof(gr_complex) * nsamples_total); // repeat for each ms
- }
-
- int offset = 0;
-
- memcpy(d_fft_if->get_inbuf() + offset, code_total, sizeof(gr_complex) * vector_length); // copy to FFT buffer
-
- d_fft_if->execute(); // Run the FFT of local code
-
- volk_32fc_conjugate_32fc(d_fft_codes_padded, d_fft_if->get_outbuf(), vector_length); // conjugate values
-
- max = 0; // initialize maximum value
-
- for (unsigned int i = 0; i < vector_length; i++) // search for maxima
- {
- if (std::abs(d_fft_codes_padded[i].real()) > max)
- {
- max = std::abs(d_fft_codes_padded[i].real());
- }
- if (std::abs(d_fft_codes_padded[i].imag()) > max)
- {
- max = std::abs(d_fft_codes_padded[i].imag());
- }
- }
-
- for (unsigned int i = 0; i < vector_length; 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 + vector_length * PRN] = lv_16sc_t(static_cast(d_fft_codes_padded[i].real() * (pow(2, 7) - 1) / max),
- static_cast(d_fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max));
- }
- }
-
- // temporary buffers that we can delete
- delete[] code;
- delete[] code_total;
- delete d_fft_if;
- delete[] d_fft_codes_padded;
-}
-
-
-gps_fpga_acquisition_8sc::~gps_fpga_acquisition_8sc()
-{
- delete[] d_all_fft_codes;
-}
-
-
-bool gps_fpga_acquisition_8sc::free()
-{
- return true;
-}
-
-
-unsigned gps_fpga_acquisition_8sc::fpga_acquisition_test_register(unsigned writeval)
-{
- unsigned 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 gps_fpga_acquisition_8sc::fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[])
-{
- short int local_code;
- unsigned int k, tmp, tmp2;
-
- // clear memory address counter
- d_map_base[4] = 0x10000000;
- for (k = 0; k < d_vector_length; k++)
- {
- tmp = fft_local_code[k].real();
- tmp2 = fft_local_code[k].imag();
- local_code = (tmp & 0xFF) | ((tmp2 * 256) & 0xFF00); // put together the real part and the imaginary part
- d_map_base[4] = 0x0C000000 | (local_code & 0xFFFF);
- }
-}
-
-
-void gps_fpga_acquisition_8sc::run_acquisition(void)
-{
- // enable interrupts
- int reenable = 1;
- write(d_fd, reinterpret_cast(&reenable), sizeof(int));
-
- d_map_base[5] = 0; // writing anything to reg 4 launches the acquisition process
-
- int irq_count;
- ssize_t nb;
- // wait for interrupt
- nb = read(d_fd, &irq_count, sizeof(irq_count));
- if (nb != sizeof(irq_count))
- {
- printf("Tracking_module Read failed to retrieve 4 bytes!\n");
- printf("Tracking_module Interrupt number %d\n", irq_count);
- }
-}
-
-
-void gps_fpga_acquisition_8sc::configure_acquisition()
-{
- d_map_base[0] = d_select_queue;
- d_map_base[1] = d_vector_length;
- d_map_base[2] = d_nsamples;
-}
-
-
-void gps_fpga_acquisition_8sc::set_phase_step(unsigned int doppler_index)
-{
- float phase_step_rad_real;
- float phase_step_rad_int_temp;
- int32_t phase_step_rad_int;
-
- int doppler = static_cast(-d_doppler_max) + d_doppler_step * doppler_index;
- float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast(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)
- if (phase_step_rad_real == 1.0)
- {
- phase_step_rad_real = MAX_PHASE_STEP_RAD;
- }
- phase_step_rad_int_temp = phase_step_rad_real * 4; // * 2^2
- phase_step_rad_int = static_cast(phase_step_rad_int_temp * (536870912)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings
-
- d_map_base[3] = phase_step_rad_int;
-}
-
-
-void gps_fpga_acquisition_8sc::read_acquisition_results(uint32_t* max_index,
- float* max_magnitude, unsigned* initial_sample, float* power_sum)
-{
- unsigned readval = 0;
- readval = d_map_base[0];
- readval = d_map_base[1];
- *initial_sample = readval;
- readval = d_map_base[2];
- *max_magnitude = static_cast(readval);
- readval = d_map_base[4];
- *power_sum = static_cast(readval);
- readval = d_map_base[3];
- *max_index = readval;
-}
-
-
-void gps_fpga_acquisition_8sc::block_samples()
-{
- d_map_base[14] = 1; // block the samples
-}
-
-
-void gps_fpga_acquisition_8sc::unblock_samples()
-{
- d_map_base[14] = 0; // unblock the samples
-}
-
-
-void gps_fpga_acquisition_8sc::open_device()
-{
- if ((d_fd = open(d_device_name.c_str(), O_RDWR | O_SYNC)) == -1)
- {
- LOG(WARNING) << "Cannot open deviceio" << d_device_name;
- }
-
- d_map_base = reinterpret_cast(mmap(NULL, PAGE_SIZE,
- PROT_READ | PROT_WRITE, MAP_SHARED, d_fd, 0));
-
- if (d_map_base == reinterpret_cast(-1))
- {
- LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory";
- }
-
- // sanity check : check test register
- // we only nee to do this when the class is created
- // but the device is not opened yet when the class is create
- // because we need to open and close the device every time we run an acquisition
- // since the same device may be used by more than one class (gps acquisition, galileo
- // acquisition, etc ..)
- unsigned writeval = TEST_REGISTER_ACQ_WRITEVAL;
- unsigned readval;
- readval = gps_fpga_acquisition_8sc::fpga_acquisition_test_register(writeval);
-
- if (writeval != readval)
- {
- LOG(WARNING) << "Acquisition test register sanity check failed";
- }
- else
- {
- LOG(INFO) << "Acquisition test register sanity check success !";
- }
-}
-
-
-void gps_fpga_acquisition_8sc::close_device()
-{
- unsigned* aux = const_cast(d_map_base);
- if (munmap(static_cast(aux), PAGE_SIZE) == -1)
- {
- printf("Failed to unmap memory uio\n");
- }
- close(d_fd);
-}
diff --git a/src/algorithms/libs/CMakeLists.txt b/src/algorithms/libs/CMakeLists.txt
index ac182801e..775ac6358 100644
--- a/src/algorithms/libs/CMakeLists.txt
+++ b/src/algorithms/libs/CMakeLists.txt
@@ -18,56 +18,81 @@
add_subdirectory(rtklib)
-set(GNSS_SPLIBS_SOURCES
- gps_l2c_signal.cc
- gps_l5_signal.cc
- galileo_e1_signal_processing.cc
- gnss_sdr_valve.cc
- gnss_sdr_sample_counter.cc
- gnss_signal_processing.cc
- gps_sdr_signal_processing.cc
- glonass_l1_signal_processing.cc
- glonass_l2_signal_processing.cc
- pass_through.cc
- galileo_e5_signal_processing.cc
- complex_byte_to_float_x2.cc
- byte_x2_to_complex_byte.cc
- cshort_to_float_x2.cc
- short_x2_to_cshort.cc
- complex_float_to_complex_byte.cc
- conjugate_cc.cc
- conjugate_sc.cc
- conjugate_ic.cc
-)
+if(ENABLE_FPGA)
+ set(GNSS_SPLIBS_SOURCES
+ gps_l2c_signal.cc
+ gps_l5_signal.cc
+ galileo_e1_signal_processing.cc
+ gnss_sdr_valve.cc
+ gnss_sdr_sample_counter.cc
+ gnss_sdr_time_counter.cc
+ gnss_signal_processing.cc
+ gps_sdr_signal_processing.cc
+ glonass_l1_signal_processing.cc
+ glonass_l2_signal_processing.cc
+ pass_through.cc
+ galileo_e5_signal_processing.cc
+ complex_byte_to_float_x2.cc
+ byte_x2_to_complex_byte.cc
+ cshort_to_float_x2.cc
+ short_x2_to_cshort.cc
+ complex_float_to_complex_byte.cc
+ conjugate_cc.cc
+ conjugate_sc.cc
+ conjugate_ic.cc
+ )
+else(ENABLE_FPGA)
+ set(GNSS_SPLIBS_SOURCES
+ gps_l2c_signal.cc
+ gps_l5_signal.cc
+ galileo_e1_signal_processing.cc
+ gnss_sdr_valve.cc
+ gnss_sdr_sample_counter.cc
+ gnss_signal_processing.cc
+ gps_sdr_signal_processing.cc
+ glonass_l1_signal_processing.cc
+ glonass_l2_signal_processing.cc
+ pass_through.cc
+ galileo_e5_signal_processing.cc
+ complex_byte_to_float_x2.cc
+ byte_x2_to_complex_byte.cc
+ cshort_to_float_x2.cc
+ short_x2_to_cshort.cc
+ complex_float_to_complex_byte.cc
+ conjugate_cc.cc
+ conjugate_sc.cc
+ conjugate_ic.cc
+ )
+endif(ENABLE_FPGA)
if(OPENCL_FOUND)
set(GNSS_SPLIBS_SOURCES ${GNSS_SPLIBS_SOURCES}
- opencl/fft_execute.cc # Needs OpenCL
- opencl/fft_setup.cc # Needs OpenCL
- opencl/fft_kernelstring.cc # Needs OpenCL
- )
+ opencl/fft_execute.cc # Needs OpenCL
+ opencl/fft_setup.cc # Needs OpenCL
+ opencl/fft_kernelstring.cc # Needs OpenCL
+ )
endif(OPENCL_FOUND)
include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/src/core/system_parameters
- ${CMAKE_SOURCE_DIR}/src/core/receiver
- ${CMAKE_SOURCE_DIR}/src/core/interfaces
- ${Boost_INCLUDE_DIRS}
- ${GLOG_INCLUDE_DIRS}
- ${GFlags_INCLUDE_DIRS}
- ${GNURADIO_RUNTIME_INCLUDE_DIRS}
- ${GNURADIO_BLOCKS_INCLUDE_DIRS}
- ${VOLK_INCLUDE_DIRS}
- ${VOLK_GNSSSDR_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/src/core/system_parameters
+ ${CMAKE_SOURCE_DIR}/src/core/receiver
+ ${CMAKE_SOURCE_DIR}/src/core/interfaces
+ ${Boost_INCLUDE_DIRS}
+ ${GLOG_INCLUDE_DIRS}
+ ${GFlags_INCLUDE_DIRS}
+ ${GNURADIO_RUNTIME_INCLUDE_DIRS}
+ ${GNURADIO_BLOCKS_INCLUDE_DIRS}
+ ${VOLK_INCLUDE_DIRS}
+ ${VOLK_GNSSSDR_INCLUDE_DIRS}
)
if(OPENCL_FOUND)
include_directories( ${OPENCL_INCLUDE_DIRS} )
if(OS_IS_MACOSX)
- set(OPT_LIBRARIES ${OPT_LIBRARIES} "-framework OpenCL")
+ set(OPT_LIBRARIES ${OPT_LIBRARIES} "-framework OpenCL")
else(OS_IS_MACOSX)
- set(OPT_LIBRARIES ${OPT_LIBRARIES} ${OPENCL_LIBRARIES})
+ set(OPT_LIBRARIES ${OPT_LIBRARIES} ${OPENCL_LIBRARIES})
endif(OS_IS_MACOSX)
endif(OPENCL_FOUND)
@@ -80,14 +105,14 @@ add_library(gnss_sp_libs ${GNSS_SPLIBS_SOURCES} ${GNSS_SPLIBS_HEADERS})
source_group(Headers FILES ${GNSS_SPLIBS_HEADERS})
target_link_libraries(gnss_sp_libs ${GNURADIO_RUNTIME_LIBRARIES}
- ${VOLK_LIBRARIES} ${ORC_LIBRARIES}
- ${VOLK_GNSSSDR_LIBRARIES} ${ORC_LIBRARIES}
- ${GFlags_LIBS}
- ${GNURADIO_BLOCKS_LIBRARIES}
- ${GNURADIO_FFT_LIBRARIES}
- ${GNURADIO_FILTER_LIBRARIES}
- ${OPT_LIBRARIES}
- gnss_rx
+ ${VOLK_LIBRARIES} ${ORC_LIBRARIES}
+ ${VOLK_GNSSSDR_LIBRARIES} ${ORC_LIBRARIES}
+ ${GFlags_LIBS}
+ ${GNURADIO_BLOCKS_LIBRARIES}
+ ${GNURADIO_FFT_LIBRARIES}
+ ${GNURADIO_FILTER_LIBRARIES}
+ ${OPT_LIBRARIES}
+ gnss_rx
)
if(NOT VOLK_GNSSSDR_FOUND)
@@ -95,9 +120,9 @@ if(NOT VOLK_GNSSSDR_FOUND)
endif(NOT VOLK_GNSSSDR_FOUND)
if(${GFLAGS_GREATER_20})
- add_definitions(-DGFLAGS_GREATER_2_0=1)
+ add_definitions(-DGFLAGS_GREATER_2_0=1)
endif(${GFLAGS_GREATER_20})
add_library(gnss_sdr_flags gnss_sdr_flags.cc gnss_sdr_flags.h)
source_group(Headers FILES gnss_sdr_flags.h)
-target_link_libraries(gnss_sdr_flags ${GFlags_LIBS})
\ No newline at end of file
+target_link_libraries(gnss_sdr_flags ${GFlags_LIBS})
diff --git a/src/algorithms/libs/gnss_sdr_time_counter.cc b/src/algorithms/libs/gnss_sdr_time_counter.cc
new file mode 100644
index 000000000..614501f36
--- /dev/null
+++ b/src/algorithms/libs/gnss_sdr_time_counter.cc
@@ -0,0 +1,126 @@
+/*!
+ * \file gnss_sdr_time_counter.cc
+ * \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks
+ * \author Antonio Ramos 2018. antonio.ramos(at)gmail.com
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "gnss_sdr_time_counter.h"
+#include "gnss_synchro.h"
+#include
+#include
+#include
+#include
+
+gnss_sdr_time_counter::gnss_sdr_time_counter() : gr::block("time_counter",
+ gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
+ gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
+{
+ set_max_noutput_items(1);
+ current_T_rx_ms = 0;
+ current_s = 0;
+ current_m = 0;
+ current_h = 0;
+ current_days = 0;
+ report_interval_ms = 1000; // default reporting 1 second
+ flag_m = false;
+ flag_h = false;
+ flag_days = false;
+}
+
+
+gnss_sdr_time_counter_sptr gnss_sdr_make_time_counter()
+{
+ gnss_sdr_time_counter_sptr counter_(new gnss_sdr_time_counter());
+ return counter_;
+}
+
+
+int gnss_sdr_time_counter::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
+ gr_vector_const_void_star &input_items __attribute__((unused)), gr_vector_void_star &output_items)
+{
+ Gnss_Synchro *out = reinterpret_cast(output_items[0]);
+ const Gnss_Synchro *in = reinterpret_cast(input_items[0]);
+ out[0] = in[0];
+ if ((current_T_rx_ms % report_interval_ms) == 0)
+ {
+ current_s++;
+ if ((current_s % 60) == 0)
+ {
+ current_s = 0;
+ current_m++;
+ flag_m = true;
+ if ((current_m % 60) == 0)
+ {
+ current_m = 0;
+ current_h++;
+ flag_h = true;
+ if ((current_h % 24) == 0)
+ {
+ current_h = 0;
+ current_days++;
+ flag_days = true;
+ }
+ }
+ }
+
+ if (flag_days)
+ {
+ std::string day;
+ if (current_days == 1)
+ {
+ day = " day ";
+ }
+ else
+ {
+ day = " days ";
+ }
+ std::cout << "Current receiver time: " << current_days << day << current_h << " h " << current_m << " min " << current_s << " s" << std::endl;
+ }
+ else
+ {
+ if (flag_h)
+ {
+ std::cout << "Current receiver time: " << current_h << " h " << current_m << " min " << current_s << " s" << std::endl;
+ }
+ else
+ {
+ if (flag_m)
+ {
+ std::cout << "Current receiver time: " << current_m << " min " << current_s << " s" << std::endl;
+ }
+ else
+ {
+ std::cout << "Current receiver time: " << current_s << " s" << std::endl;
+ }
+ }
+ }
+ }
+ current_T_rx_ms++;
+ consume_each(1);
+ return 1;
+}
diff --git a/src/algorithms/libs/gnss_sdr_time_counter.h b/src/algorithms/libs/gnss_sdr_time_counter.h
new file mode 100644
index 000000000..4a424ce12
--- /dev/null
+++ b/src/algorithms/libs/gnss_sdr_time_counter.h
@@ -0,0 +1,64 @@
+/*!
+ * \file gnss_sdr_time_counter.h
+ * \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks
+ * \author Antonio Ramos 2018. antonio.ramosdet(at)gmail.com
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+#ifndef GNSS_SDR_TIME_COUNTER_H_
+#define GNSS_SDR_TIME_COUNTER_H_
+
+#include
+#include
+
+
+class gnss_sdr_time_counter;
+
+typedef boost::shared_ptr gnss_sdr_time_counter_sptr;
+
+gnss_sdr_time_counter_sptr gnss_sdr_make_time_counter();
+
+class gnss_sdr_time_counter : public gr::block
+{
+private:
+ gnss_sdr_time_counter();
+ long long int current_T_rx_ms; // Receiver time in ms since the beginning of the run
+ unsigned int current_s; // Receiver time in seconds, modulo 60
+ bool flag_m; // True if the receiver has been running for at least 1 minute
+ unsigned int current_m; // Receiver time in minutes, modulo 60
+ bool flag_h; // True if the receiver has been running for at least 1 hour
+ unsigned int current_h; // Receiver time in hours, modulo 24
+ bool flag_days; // True if the receiver has been running for at least 1 day
+ unsigned int current_days; // Receiver time in days since the beginning of the run
+ int report_interval_ms;
+
+public:
+ friend gnss_sdr_time_counter_sptr gnss_sdr_make_time_counter();
+ int general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
+ gr_vector_const_void_star &input_items __attribute__((unused)), gr_vector_void_star &output_items);
+};
+
+#endif /*GNSS_SDR_SAMPLE_COUNTER_H_*/
diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc
index 06f0efdcd..159d5f1fb 100644
--- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc
+++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc
@@ -64,7 +64,7 @@ hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels_in,
T_rx_s = 0.0;
T_rx_step_s = 0.001; // 1 ms
max_delta = 1.5; // 1.5 s
- d_latency = 0.3; // 300 ms
+ d_latency = 0.5; // 300 ms
valid_channels.resize(d_nchannels, false);
d_num_valid_channels = 0;
d_gnss_synchro_history = new Gnss_circular_deque(static_cast(max_delta * 1000.0), d_nchannels);
diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt
index 2fb8f4be8..ededc5dc7 100644
--- a/src/algorithms/signal_source/adapters/CMakeLists.txt
+++ b/src/algorithms/signal_source/adapters/CMakeLists.txt
@@ -35,6 +35,20 @@ if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2)
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS})
endif(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2)
+if(ENABLE_AD9361)
+ find_package(libiio REQUIRED)
+ if(NOT LIBIIO_FOUND)
+ message(STATUS "gnuradio-iio not found, its installation is required.")
+ message(STATUS "Please build and install the following projects:")
+ message(STATUS " * libiio from https://github.com/analogdevicesinc/libiio")
+ message(STATUS " * libad9361-iio from https://github.com/analogdevicesinc/libad9361-iio")
+ message(STATUS " * gnuradio-iio from https://github.com/analogdevicesinc/gr-iio")
+ message(FATAL_ERROR "gnuradio-iio required for building gnss-sdr with this option enabled")
+ endif(NOT LIBIIO_FOUND)
+ set(OPT_LIBRARIES ${OPT_LIBRARIES} ${LIBIIO_LIBRARIES})
+ set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${LIBIIO_INCLUDE_DIRS})
+endif(ENABLE_AD9361)
+
if(ENABLE_PLUTOSDR)
##############################################
@@ -55,6 +69,16 @@ if(ENABLE_FMCOMMS2)
endif(IIO_FOUND)
endif(ENABLE_FMCOMMS2)
+if(ENABLE_AD9361)
+ ###############################################
+ # AD9361 DIRECT TO FPGA Hardware
+ ###############################################
+ if(LIBIIO_FOUND)
+ set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} ad9361_fpga_signal_source.cc)
+ endif(LIBIIO_FOUND)
+endif(ENABLE_AD9361)
+
+
if(ENABLE_GN3S)
##############################################
diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc
new file mode 100644
index 000000000..cba4e5439
--- /dev/null
+++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc
@@ -0,0 +1,160 @@
+/*!
+ * \file ad9361_fpga_signal_source.cc
+ * \brief signal source for Analog Devices front-end AD9361 connected directly to FPGA accelerators.
+ * This source implements only the AD9361 control. It is NOT compatible with conventional SDR acquisition and tracking blocks.
+ * Please use the fmcomms2 source if conventional SDR acquisition and tracking is selected in the configuration file.
+ * \author Javier Arribas, jarribas(at)cttc.es
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "ad9361_fpga_signal_source.h"
+#include "configuration_interface.h"
+#include "ad9361_manager.h"
+#include "GPS_L1_CA.h"
+#include "GPS_L2C.h"
+#include
+#include
+#include
+#include
+
+#ifdef __APPLE__
+#include
+#else
+#include
+#endif
+
+Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(ConfigurationInterface* configuration,
+ std::string role, unsigned int in_stream, unsigned int out_stream,
+ boost::shared_ptr queue) :
+ role_(role), in_stream_(in_stream), out_stream_(out_stream),
+ queue_(queue)
+{
+ std::string default_item_type = "gr_complex";
+ std::string default_dump_file = "./data/signal_source.dat";
+ freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ);
+ sample_rate_ = configuration->property(role + ".sampling_frequency", 2600000);
+ bandwidth_ = configuration->property(role + ".bandwidth", 2000000);
+ rx1_en_ = configuration->property(role + ".rx1_enable", true);
+ rx2_en_ = configuration->property(role + ".rx2_enable", false);
+ buffer_size_ = configuration->property(role + ".buffer_size", 0xA0000);
+ quadrature_ = configuration->property(role + ".quadrature", true);
+ rf_dc_ = configuration->property(role + ".rf_dc", true);
+ bb_dc_ = configuration->property(role + ".bb_dc", true);
+ gain_mode_rx1_ = configuration->property(role + ".gain_mode_rx1", std::string("manual"));
+ gain_mode_rx2_ = configuration->property(role + ".gain_mode_rx2", std::string("manual"));
+ rf_gain_rx1_ = configuration->property(role + ".gain_rx1", 64.0);
+ rf_gain_rx2_ = configuration->property(role + ".gain_rx2", 64.0);
+ rf_port_select_ = configuration->property(role + ".rf_port_select", std::string("A_BALANCED"));
+ filter_file_ = configuration->property(role + ".filter_file", std::string(""));
+ filter_auto_ = configuration->property(role + ".filter_auto", true);
+ item_type_ = configuration->property(role + ".item_type", default_item_type);
+ samples_ = configuration->property(role + ".samples", 0);
+ dump_ = configuration->property(role + ".dump", false);
+ dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file);
+
+ enable_dds_lo_=configuration->property(role + ".enable_dds_lo", false);
+ freq_rf_tx_hz_=configuration->property(role + ".freq_rf_tx_hz", GPS_L1_FREQ_HZ-GPS_L2_FREQ_HZ-1000);
+ freq_dds_tx_hz_=configuration->property(role + ".freq_dds_tx_hz", 1000);
+ scale_dds_dbfs_=configuration->property(role + ".scale_dds_dbfs", -3.0);
+ phase_dds_deg_=configuration->property(role + ".phase_dds_deg", 0.0);
+ tx_attenuation_db_=configuration->property(role + ".tx_attenuation_db", 0.0);
+
+ item_size_ = sizeof(gr_complex);
+
+ std::cout << "device address: " << uri_ << std::endl;
+ std::cout << "LO frequency : " << freq_ << " Hz" << std::endl;
+ std::cout << "sample rate: " << sample_rate_ << " Hz" << std::endl;
+
+ config_ad9361_rx_local(bandwidth_,
+ sample_rate_,
+ freq_,
+ rf_port_select_,
+ gain_mode_rx1_,
+ gain_mode_rx2_,
+ rf_gain_rx1_,
+ rf_gain_rx2_);
+
+ //LOCAL OSCILLATOR DDS GENERATOR FOR DUAL FREQUENCY OPERATION
+ if (enable_dds_lo_==true)
+ {
+ config_ad9361_lo_local(bandwidth_,
+ sample_rate_,
+ freq_rf_tx_hz_,
+ tx_attenuation_db_,
+ freq_dds_tx_hz_,
+ scale_dds_dbfs_);
+ }
+
+ // turn switch to A/D position
+ std::string default_device_name = "/dev/uio13";
+ std::string device_name = configuration->property(role + ".devicename", default_device_name);
+ int switch_position = configuration->property(role + ".switch_position", 0);
+ switch_fpga = std::make_shared (device_name);
+ switch_fpga->set_switch_position(switch_position);
+}
+
+
+Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource()
+{
+ /* cleanup and exit */
+ //std::cout<<"* AD9361 Disabling streaming channels\n";
+ //if (rx0_i) { iio_channel_disable(rx0_i); }
+ //if (rx0_q) { iio_channel_disable(rx0_q); }
+
+ if (enable_dds_lo_)
+ {
+ ad9361_disable_lo_local();
+ }
+
+ // std::cout<<"* AD9361 Destroying context\n";
+ //if (ctx) { iio_context_destroy(ctx); }
+}
+
+
+void Ad9361FpgaSignalSource::connect(gr::top_block_sptr top_block)
+{
+ DLOG(INFO) << "AD9361 FPGA source nothing to connect";
+}
+
+
+void Ad9361FpgaSignalSource::disconnect(gr::top_block_sptr top_block)
+{
+ DLOG(INFO) << "AD9361 FPGA source nothing to disconnect";
+}
+
+
+gr::basic_block_sptr Ad9361FpgaSignalSource::get_left_block()
+{
+ LOG(WARNING) << "Trying to get signal source left block.";
+ return gr::basic_block_sptr();
+}
+
+
+gr::basic_block_sptr Ad9361FpgaSignalSource::get_right_block()
+{
+ LOG(WARNING) << "Trying to get AD9361 FPGA signal source right block.";
+ return gr::basic_block_sptr();
+}
diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h
new file mode 100644
index 000000000..6110a63c3
--- /dev/null
+++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h
@@ -0,0 +1,120 @@
+/*!
+ * \file ad9361_fpga_signal_source.h
+ * \brief signal source for Analog Devices front-end AD9361 connected directly to FPGA accelerators.
+ * This source implements only the AD9361 control. It is NOT compatible with conventional SDR acquisition and tracking blocks.
+ * Please use the fmcomms2 source if conventional SDR acquisition and tracking is selected in the configuration file.
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H_
+#define GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H_
+
+#include "gnss_block_interface.h"
+#include "fpga_switch.h"
+
+#include
+#include
+#include
+
+class ConfigurationInterface;
+
+class Ad9361FpgaSignalSource: public GNSSBlockInterface
+{
+public:
+ Ad9361FpgaSignalSource(ConfigurationInterface* configuration,
+ std::string role, unsigned int in_stream,
+ unsigned int out_stream, boost::shared_ptr queue);
+
+ virtual ~Ad9361FpgaSignalSource();
+
+ inline std::string role() override
+ {
+ return role_;
+ }
+
+ /*!
+ * \brief Returns "Ad9361_Fpga_Signal_Source"
+ */
+ inline std::string implementation() override
+ {
+ return "Ad9361_Fpga_Signal_Source";
+ }
+
+ inline size_t item_size() override
+ {
+ return item_size_;
+ }
+
+ void connect(gr::top_block_sptr top_block) override;
+ void disconnect(gr::top_block_sptr top_block) override;
+ gr::basic_block_sptr get_left_block() override;
+ gr::basic_block_sptr get_right_block() override;
+
+private:
+ std::string role_;
+
+ // Front-end settings
+ std::string uri_;//device direction
+ unsigned long freq_; //frequency of local oscilator
+ unsigned long sample_rate_;
+ unsigned long bandwidth_;
+ unsigned long buffer_size_; //reception buffer
+ bool rx1_en_;
+ bool rx2_en_;
+ bool quadrature_;
+ bool rf_dc_;
+ bool bb_dc_;
+ std::string gain_mode_rx1_;
+ std::string gain_mode_rx2_;
+ double rf_gain_rx1_;
+ double rf_gain_rx2_;
+ std::string rf_port_select_;
+ std::string filter_file_;
+ bool filter_auto_;
+
+ //DDS configuration for LO generation for external mixer
+ bool enable_dds_lo_;
+ unsigned long freq_rf_tx_hz_;
+ unsigned long freq_dds_tx_hz_;
+ double scale_dds_dbfs_;
+ double phase_dds_deg_;
+ double tx_attenuation_db_;
+
+ unsigned int in_stream_;
+ unsigned int out_stream_;
+
+ std::string item_type_;
+ size_t item_size_;
+ long samples_;
+ bool dump_;
+ std::string dump_filename_;
+
+ boost::shared_ptr queue_;
+
+ std::shared_ptr switch_fpga;
+};
+
+#endif /*GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H_*/
diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt
index 5a35a7992..c8f676b49 100644
--- a/src/algorithms/signal_source/libs/CMakeLists.txt
+++ b/src/algorithms/signal_source/libs/CMakeLists.txt
@@ -28,7 +28,10 @@ if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2)
endif(NOT IIO_FOUND)
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${IIO_LIBRARIES})
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS})
-
+
+endif(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2)
+
+if(ENABLE_FMCOMMS2 OR ENABLE_AD9361)
find_package(libiio REQUIRED)
if(NOT LIBIIO_FOUND)
message(STATUS "gnuradio-iio not found, its installation is required.")
@@ -40,37 +43,38 @@ if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2)
endif(NOT LIBIIO_FOUND)
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${LIBIIO_LIBRARIES})
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${LIBIIO_INCLUDE_DIRS})
-
-endif(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2)
-if(ENABLE_FMCOMMS2)
- ###############################################
+ ###############################################
# FMCOMMS2 based SDR Hardware
###############################################
if(IIO_FOUND)
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ad9361_manager.cc)
endif(IIO_FOUND)
-endif(ENABLE_FMCOMMS2)
+
+endif(ENABLE_FMCOMMS2 OR ENABLE_AD9361)
+
+if(ENABLE_AD9361)
+ set(OPT_SIGNAL_SOURCE_LIB_SOURCES ad9361_manager.cc)
+endif(ENABLE_AD9361)
+
+if(ENABLE_FPGA)
+ SET(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_switch.cc)
+endif(ENABLE_FPGA)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${Boost_INCLUDE_DIRS}
+ ${OPT_DRIVER_INCLUDE_DIRS}
+)
set (SIGNAL_SOURCE_LIB_SOURCES
rtl_tcp_commands.cc
rtl_tcp_dongle_info.cc
${OPT_SIGNAL_SOURCE_LIB_SOURCES})
-include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${Boost_INCLUDE_DIRS}
- ${GLOG_INCLUDE_DIRS}
- ${GFlags_INCLUDE_DIRS}
- ${OPT_DRIVER_INCLUDE_DIRS}
-)
-
-
file(GLOB SIGNAL_SOURCE_LIB_HEADERS "*.h")
list(SORT SIGNAL_SOURCE_LIB_HEADERS)
-list(SORT SIGNAL_SOURCE_LIB_SOURCES)
add_library(signal_source_lib ${SIGNAL_SOURCE_LIB_SOURCES} ${SIGNAL_SOURCE_LIB_HEADERS})
source_group(Headers FILES ${SIGNAL_SOURCE_LIB_HEADERS})
-add_dependencies(signal_source_lib glog-${glog_RELEASE})
-target_link_libraries(signal_source_lib ${OPT_LIBRARIES})
+target_link_libraries(signal_source_lib ${OPT_LIBRARIES})
diff --git a/src/algorithms/signal_source/libs/fpga_switch.cc b/src/algorithms/signal_source/libs/fpga_switch.cc
new file mode 100644
index 000000000..aae7da979
--- /dev/null
+++ b/src/algorithms/signal_source/libs/fpga_switch.cc
@@ -0,0 +1,137 @@
+/*!
+ * \file fpga_switch.cc
+ * \brief Switch that connects the HW accelerator queues to the analog front end or the DMA.
+ * \authors
+ * - Marc Majoral, 2017. mmajoral(at)cttc.cat
+ *
- Javier Arribas, 2015. jarribas(at)cttc.es
+ *
+ *
+ * Class that controls a switch in the FPGA
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "fpga_switch.h"
+#include
+
+// FPGA stuff
+#include
+
+// libraries used by DMA test code and GIPO test code
+#include
+#include
+#include
+#include
+
+// libraries used by DMA test code
+#include
+#include
+#include
+#include
+
+// libraries used by GPIO test code
+#include
+#include
+#include
+
+// logging
+#include
+
+// string manipulation
+#include
+
+// constants
+#define PAGE_SIZE 0x10000
+#define TEST_REGISTER_TRACK_WRITEVAL 0x55AA
+
+fpga_switch::fpga_switch(std::string device_name)
+{
+ if ((d_device_descriptor = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1)
+ {
+ LOG(WARNING) << "Cannot open deviceio" << device_name;
+ printf("switch memory successfully mapped\n");
+ }
+ d_map_base = reinterpret_cast(mmap(NULL, PAGE_SIZE,
+ PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0));
+
+ if (d_map_base == reinterpret_cast(-1))
+ {
+ LOG(WARNING) << "Cannot map the FPGA switch module into tracking memory";
+ printf("could not map switch memory\n");
+ }
+
+ // sanity check : check test register
+ unsigned writeval = TEST_REGISTER_TRACK_WRITEVAL;
+ unsigned readval;
+ readval = fpga_switch::fpga_switch_test_register(writeval);
+ if (writeval != readval)
+ {
+ LOG(WARNING) << "Test register sanity check failed";
+ }
+ else
+ {
+ LOG(INFO) << "Test register sanity check success !";
+ }
+
+ DLOG(INFO) << "Switch FPGA class created";
+}
+
+
+fpga_switch::~fpga_switch()
+{
+ close_device();
+}
+
+
+void fpga_switch::set_switch_position(int switch_position)
+{
+ d_map_base[0] = switch_position;
+}
+
+
+unsigned fpga_switch::fpga_switch_test_register(
+ unsigned writeval)
+{
+ unsigned readval;
+ // write value to test register
+ d_map_base[3] = writeval;
+ // read value from test register
+ readval = d_map_base[3];
+ // return read value
+ return readval;
+}
+
+
+void fpga_switch::close_device()
+{
+ unsigned *aux = const_cast(d_map_base);
+ if (munmap(static_cast(aux), PAGE_SIZE) == -1)
+ {
+ printf("Failed to unmap memory uio\n");
+ }
+
+ close(d_device_descriptor);
+}
diff --git a/src/algorithms/signal_source/libs/fpga_switch.h b/src/algorithms/signal_source/libs/fpga_switch.h
new file mode 100644
index 000000000..395aff425
--- /dev/null
+++ b/src/algorithms/signal_source/libs/fpga_switch.h
@@ -0,0 +1,60 @@
+/*!
+ * \file fpga_switch.h
+ * \brief Switch that connects the HW accelerator queues to the analog front end or the DMA.
+ * \authors
+ * - Marc Majoral, 2017. mmajoral(at)cttc.cat
+ *
- Javier Arribas, 2016. jarribas(at)cttc.es
+ *
+ *
+ * Class that controls a switch in the FPGA
+ *
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef GNSS_SDR_FPGA_SWITCH_H_
+#define GNSS_SDR_FPGA_SWITCH_H_
+
+#include
+
+#define MAX_LENGTH_DEVICEIO_NAME 50
+
+class fpga_switch
+{
+public:
+ fpga_switch(std::string device_name);
+ ~fpga_switch();
+ void set_switch_position(int switch_position);
+
+private:
+ int d_device_descriptor; // driver descriptor
+ volatile unsigned *d_map_base; // driver memory map
+
+ // private functions
+ unsigned fpga_switch_test_register(unsigned writeval);
+ void close_device(void);
+};
+
+#endif /* GNSS_SDR_FPGA_SWITCH_H_ */
diff --git a/src/algorithms/tracking/adapters/CMakeLists.txt b/src/algorithms/tracking/adapters/CMakeLists.txt
index 044e3287a..6b60f35b1 100644
--- a/src/algorithms/tracking/adapters/CMakeLists.txt
+++ b/src/algorithms/tracking/adapters/CMakeLists.txt
@@ -22,7 +22,7 @@ if(ENABLE_CUDA)
endif(ENABLE_CUDA)
if(ENABLE_FPGA)
- SET(OPT_TRACKING_ADAPTERS ${OPT_TRACKING_ADAPTERS} gps_l1_ca_dll_pll_c_aid_tracking_fpga.cc)
+ SET(OPT_TRACKING_ADAPTERS ${OPT_TRACKING_ADAPTERS} gps_l1_ca_dll_pll_tracking_fpga.cc)
endif(ENABLE_FPGA)
set(TRACKING_ADAPTER_SOURCES
diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.cc
deleted file mode 100644
index 8f6f5972c..000000000
--- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-/*!
- * \file gps_l1_ca_dll_pll_c_aid_tracking_fpga.cc
- * \brief Implementation of an adapter of a DLL+PLL tracking loop block
- * for GPS L1 C/A to a TrackingInterface
- * \author Marc Majoral, 2017. mmajoral(at)cttc.cat
- * Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
- * Javier Arribas, 2011. jarribas(at)cttc.es
- *
- * 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-2017 (see AUTHORS file for a list of contributors)
- *
- * GNSS-SDR is a software defined Global Navigation
- * Satellite Systems receiver
- *
- * This file is part of GNSS-SDR.
- *
- * GNSS-SDR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GNSS-SDR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNSS-SDR. If not, see .
- *
- * -------------------------------------------------------------------------
- */
-
-#include "gps_l1_ca_dll_pll_c_aid_tracking_fpga.h"
-#include
-#include "GPS_L1_CA.h"
-#include "configuration_interface.h"
-#include "gnss_sdr_flags.h"
-
-
-using google::LogMessage;
-
-GpsL1CaDllPllCAidTrackingFpga::GpsL1CaDllPllCAidTrackingFpga(
- ConfigurationInterface* configuration, std::string role,
- unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
-{
- DLOG(INFO) << "role " << role;
- //################# CONFIGURATION PARAMETERS ########################
- int fs_in;
- int vector_length;
- int f_if;
- bool dump;
- std::string dump_filename;
- std::string default_item_type = "cshort";
- float pll_bw_hz;
- float pll_bw_narrow_hz;
- float dll_bw_hz;
- float dll_bw_narrow_hz;
- float early_late_space_chips;
- std::string device_name;
- unsigned int device_base;
-
- item_type_ = configuration->property(role + ".item_type", default_item_type);
- int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
- fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
- f_if = configuration->property(role + ".if", 0);
- dump = configuration->property(role + ".dump", false);
- pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0);
- if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz);
- dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0);
- if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast(FLAGS_dll_bw_hz);
- pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 20.0);
- dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 2.0);
- int extend_correlation_ms;
- extend_correlation_ms = configuration->property(role + ".extend_correlation_ms", 1);
-
- early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
- std::string default_dump_filename = "./track_ch";
- dump_filename = configuration->property(role + ".dump_filename", default_dump_filename);
- std::string default_device_name = "/dev/uio";
- device_name = configuration->property(role + ".devicename", default_device_name);
- device_base = configuration->property(role + ".device_base", 1);
- vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
-
- //################# MAKE TRACKING GNURadio object ###################
-
- if (item_type_.compare("cshort") == 0)
- {
- item_size_ = sizeof(lv_16sc_t);
- tracking_fpga_sc = gps_l1_ca_dll_pll_c_aid_make_tracking_fpga_sc(
- f_if, fs_in, vector_length, dump, dump_filename, pll_bw_hz,
- dll_bw_hz, pll_bw_narrow_hz, dll_bw_narrow_hz,
- extend_correlation_ms, early_late_space_chips, device_name,
- device_base);
- DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")";
- }
- else
- {
- item_size_ = sizeof(lv_16sc_t);
- // LOG(WARNING) << item_type_ << " unknown tracking item type";
- LOG(WARNING) << item_type_
- << " the tracking item type for the FPGA tracking test has to be cshort";
- }
-
- channel_ = 0;
-}
-
-
-GpsL1CaDllPllCAidTrackingFpga::~GpsL1CaDllPllCAidTrackingFpga()
-{
- LOG(INFO) << "gspl1cadllpllcaidtrackingfpga destructor called";
-}
-
-
-void GpsL1CaDllPllCAidTrackingFpga::start_tracking()
-{
- if (item_type_.compare("cshort") == 0)
- {
- tracking_fpga_sc->start_tracking();
- }
- else
- {
- // LOG(WARNING) << item_type_ << " unknown tracking item type";
- LOG(WARNING) << item_type_
- << " the tracking item type for the FPGA tracking test has to be cshort";
- }
-}
-
-
-/*
- * Set tracking channel unique ID
- */
-void GpsL1CaDllPllCAidTrackingFpga::set_channel(unsigned int channel)
-{
- channel_ = channel;
-
- if (item_type_.compare("cshort") == 0)
- {
- tracking_fpga_sc->set_channel(channel);
- }
- else
- {
- // LOG(WARNING) << item_type_ << " unknown tracking item type";
- LOG(WARNING) << item_type_
- << " the tracking item type for the FPGA tracking test has to be cshort";
- }
-}
-
-
-void GpsL1CaDllPllCAidTrackingFpga::set_gnss_synchro(
- Gnss_Synchro* p_gnss_synchro)
-{
- if (item_type_.compare("cshort") == 0)
- {
- tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro);
- }
- else
- {
- // LOG(WARNING) << item_type_ << " unknown tracking item type";
- LOG(WARNING) << item_type_
- << " the tracking item type for the FPGA tracking test has to be cshort";
- }
-}
-
-
-void GpsL1CaDllPllCAidTrackingFpga::connect(gr::top_block_sptr top_block)
-{
- if (top_block)
- { /* top_block is not null */
- };
- //nothing to connect, now the tracking uses gr_sync_decimator
-}
-
-
-void GpsL1CaDllPllCAidTrackingFpga::disconnect(gr::top_block_sptr top_block)
-{
- if (top_block)
- { /* top_block is not null */
- };
- //nothing to disconnect, now the tracking uses gr_sync_decimator
-}
-
-
-// CONVERT TO SOURCE
-gr::basic_block_sptr GpsL1CaDllPllCAidTrackingFpga::get_left_block()
-{
- if (item_type_.compare("cshort") == 0)
- {
- return tracking_fpga_sc;
- }
- else
- {
- //LOG(WARNING) << item_type_ << " unknown tracking item type";
- LOG(WARNING) << item_type_
- << " the tracking item type for the FPGA tracking test has to be cshort";
- return nullptr;
- }
-}
-
-
-gr::basic_block_sptr GpsL1CaDllPllCAidTrackingFpga::get_right_block()
-{
- if (item_type_.compare("cshort") == 0)
- {
- return tracking_fpga_sc;
- }
- else
- {
- //LOG(WARNING) << item_type_ << " unknown tracking item type";
- LOG(WARNING) << item_type_
- << " the tracking item type for the FPGA tracking test has to be cshort";
- return nullptr;
- }
-}
-
-
-void GpsL1CaDllPllCAidTrackingFpga::reset(void)
-{
- tracking_fpga_sc->reset();
-}
diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc
new file mode 100644
index 000000000..77f667407
--- /dev/null
+++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc
@@ -0,0 +1,162 @@
+/*!
+ * \file gps_l1_ca_dll_pll_tracking.cc
+ * \brief Implementation of an adapter of a DLL+PLL tracking loop block
+ * for GPS L1 C/A to a TrackingInterface
+ * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
+ * Javier Arribas, 2011. jarribas(at)cttc.es
+ *
+ * Code DLL + carrier PLL according to the algorithms described in:
+ * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
+ * A Software-Defined GPS and Galileo Receiver. A Single-Frequency
+ * Approach, Birkhauser, 2007
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+
+#include "gps_l1_ca_dll_pll_tracking_fpga.h"
+#include "configuration_interface.h"
+#include "GPS_L1_CA.h"
+#include
+
+
+using google::LogMessage;
+
+GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
+ ConfigurationInterface* configuration, std::string role,
+ unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
+{
+ DLOG(INFO) << "role " << role;
+ //################# CONFIGURATION PARAMETERS ########################
+ int fs_in;
+ int vector_length;
+ int f_if;
+ bool dump;
+ std::string dump_filename;
+ std::string item_type;
+ //std::string default_item_type = "gr_complex";
+ std::string default_item_type = "cshort";
+ float pll_bw_hz;
+ float dll_bw_hz;
+ float early_late_space_chips;
+ item_type = configuration->property(role + ".item_type", default_item_type);
+ int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
+ std::string device_name;
+ unsigned int device_base;
+ std::string default_device_name = "/dev/uio";
+ device_name = configuration->property(role + ".devicename", default_device_name);
+ device_base = configuration->property(role + ".device_base", 1);
+ fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
+ f_if = configuration->property(role + ".if", 0);
+ dump = configuration->property(role + ".dump", false);
+ pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0);
+ dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0);
+ early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
+ std::string default_dump_filename = "./track_ch";
+ dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); //unused!
+ vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
+ if (item_type.compare("cshort") == 0)
+ {
+ item_size_ = sizeof(lv_16sc_t);
+ tracking_fpga_sc = gps_l1_ca_dll_pll_make_tracking_fpga_sc(
+ f_if, fs_in, vector_length, dump, dump_filename, pll_bw_hz,
+ dll_bw_hz, early_late_space_chips, device_name,
+ device_base);
+ DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id()
+ << ")";
+ }
+ else
+ {
+ item_size_ = sizeof(lv_16sc_t);
+ // LOG(WARNING) << item_type_ << " unknown tracking item type";
+ LOG(WARNING) << item_type
+ << " the tracking item type for the FPGA tracking test has to be cshort";
+ }
+ channel_ = 0;
+ DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")";
+}
+
+
+GpsL1CaDllPllTrackingFpga::~GpsL1CaDllPllTrackingFpga()
+{
+}
+
+
+void GpsL1CaDllPllTrackingFpga::start_tracking()
+{
+ tracking_fpga_sc->start_tracking();
+}
+
+
+/*
+ * Set tracking channel unique ID
+ */
+void GpsL1CaDllPllTrackingFpga::set_channel(unsigned int channel)
+{
+ channel_ = channel;
+ tracking_fpga_sc->set_channel(channel);
+}
+
+
+void GpsL1CaDllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
+{
+ tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro);
+}
+
+
+void GpsL1CaDllPllTrackingFpga::connect(gr::top_block_sptr top_block)
+{
+ if (top_block)
+ { /* top_block is not null */
+ };
+ //nothing to connect, now the tracking uses gr_sync_decimator
+}
+
+
+void GpsL1CaDllPllTrackingFpga::disconnect(gr::top_block_sptr top_block)
+{
+ if (top_block)
+ { /* top_block is not null */
+ };
+ //nothing to disconnect, now the tracking uses gr_sync_decimator
+}
+
+
+gr::basic_block_sptr GpsL1CaDllPllTrackingFpga::get_left_block()
+{
+ return tracking_fpga_sc;
+}
+
+
+gr::basic_block_sptr GpsL1CaDllPllTrackingFpga::get_right_block()
+{
+ return tracking_fpga_sc;
+}
+
+
+void GpsL1CaDllPllTrackingFpga::reset(void)
+{
+ // tracking_fpga_sc->reset();
+}
diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h
similarity index 73%
rename from src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.h
rename to src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h
index e61c7c57b..0abb88220 100644
--- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking_fpga.h
+++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h
@@ -1,9 +1,8 @@
/*!
- * \file gps_l1_ca_dll_pll_c_aid_tracking_fpga.h
+ * \file gps_l1_ca_dll_pll_tracking.h
* \brief Interface of an adapter of a DLL+PLL tracking loop block
* for GPS L1 C/A to a TrackingInterface
- * \author Marc Majoral, 2017. mmajoral(at)cttc.cat
- * Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
+ * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
* Javier Arribas, 2011. jarribas(at)cttc.es
*
* Code DLL + carrier PLL according to the algorithms described in:
@@ -13,7 +12,7 @@
*
* -------------------------------------------------------------------------
*
- * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
+ * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@@ -36,36 +35,38 @@
* -------------------------------------------------------------------------
*/
-#ifndef GNSS_SDR_GPS_L1_CA_DLL_PLL_C_AID_TRACKING_FPGA__H_
-#define GNSS_SDR_GPS_L1_CA_DLL_PLL_C_AID_TRACKING_FPGA__H_
+#ifndef GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_H_
+#define GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_H_
+
-#include
#include "tracking_interface.h"
-#include "gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h"
+#include "gps_l1_ca_dll_pll_tracking_fpga_sc.h"
+#include
class ConfigurationInterface;
/*!
* \brief This class implements a code DLL + carrier PLL tracking loop
*/
-class GpsL1CaDllPllCAidTrackingFpga : public TrackingInterface
+class GpsL1CaDllPllTrackingFpga : public TrackingInterface
{
public:
- GpsL1CaDllPllCAidTrackingFpga(ConfigurationInterface* configuration,
- std::string role, unsigned int in_streams,
+ GpsL1CaDllPllTrackingFpga(ConfigurationInterface* configuration,
+ std::string role,
+ unsigned int in_streams,
unsigned int out_streams);
- virtual ~GpsL1CaDllPllCAidTrackingFpga();
+ virtual ~GpsL1CaDllPllTrackingFpga();
inline std::string role() override
{
return role_;
}
- //! Returns "GPS_L1_CA_DLL_PLL_C_Aid_Tracking_Fpga"
+ //! Returns "GPS_L1_CA_DLL_PLL_Tracking_Fpga"
inline std::string implementation() override
{
- return "GPS_L1_CA_DLL_PLL_C_Aid_Tracking_Fpga";
+ return "GPS_L1_CA_DLL_PLL_Tracking_Fpga";
}
inline size_t item_size() override
@@ -75,7 +76,6 @@ public:
void connect(gr::top_block_sptr top_block) override;
void disconnect(gr::top_block_sptr top_block) override;
- // CONVERT TO SOURCE
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_right_block() override;
@@ -95,13 +95,13 @@ public:
void reset(void);
private:
- gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc_sptr tracking_fpga_sc;
+ //gps_l1_ca_dll_pll_tracking_cc_sptr tracking_;
+ gps_l1_ca_dll_pll_tracking_fpga_sc_sptr tracking_fpga_sc;
size_t item_size_;
- std::string item_type_;
unsigned int channel_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
};
-#endif // GNSS_SDR_GPS_L1_CA_DLL_PLL_C_AID_TRACKING_FPGA__H_
+#endif // GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_H_
diff --git a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt
index 535a38663..4cb869a79 100644
--- a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt
+++ b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt
@@ -23,7 +23,7 @@ if(ENABLE_CUDA)
endif(ENABLE_CUDA)
if(ENABLE_FPGA)
- set(OPT_TRACKING_BLOCKS ${OPT_TRACKING_BLOCKS} gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.cc)
+ set(OPT_TRACKING_BLOCKS ${OPT_TRACKING_BLOCKS} gps_l1_ca_dll_pll_tracking_fpga_sc.cc)
endif(ENABLE_FPGA)
set(TRACKING_GR_BLOCKS_SOURCES
diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_fpga_sc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_fpga_sc.cc
new file mode 100644
index 000000000..30a99b5d5
--- /dev/null
+++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_fpga_sc.cc
@@ -0,0 +1,540 @@
+/*!
+ * \file gps_l1_ca_dll_pll_tracking_cc.cc
+ * \brief Implementation of a code DLL + carrier PLL tracking block
+ * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
+ * Javier Arribas, 2011. jarribas(at)cttc.es
+ *
+ * Code DLL + carrier PLL according to the algorithms described in:
+ * [1] K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
+ * A Software-Defined GPS and Galileo Receiver. A Single-Frequency
+ * Approach, Birkhauser, 2007
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "gps_l1_ca_dll_pll_tracking_fpga_sc.h"
+#include "control_message_factory.h"
+#include "gnss_sdr_flags.h"
+#include "GPS_L1_CA.h"
+#include "gps_sdr_signal_processing.h"
+#include "lock_detectors.h"
+#include "tracking_discriminators.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+using google::LogMessage;
+
+gps_l1_ca_dll_pll_tracking_fpga_sc_sptr
+gps_l1_ca_dll_pll_make_tracking_fpga_sc(
+ long if_freq,
+ long fs_in,
+ unsigned int vector_length,
+ bool dump,
+ std::string dump_filename,
+ float pll_bw_hz,
+ float dll_bw_hz,
+ float early_late_space_chips,
+ std::string device_name,
+ unsigned int device_base)
+{
+ return gps_l1_ca_dll_pll_tracking_fpga_sc_sptr(new Gps_L1_Ca_Dll_Pll_Tracking_fpga_sc(if_freq,
+ fs_in, vector_length, dump, dump_filename, pll_bw_hz, dll_bw_hz, early_late_space_chips, device_name, device_base));
+}
+
+
+Gps_L1_Ca_Dll_Pll_Tracking_fpga_sc::Gps_L1_Ca_Dll_Pll_Tracking_fpga_sc(
+ long if_freq,
+ long fs_in,
+ unsigned int vector_length,
+ bool dump,
+ std::string dump_filename,
+ float pll_bw_hz,
+ float dll_bw_hz,
+ float early_late_space_chips,
+ std::string device_name,
+ unsigned int device_base) : gr::block("Gps_L1_Ca_Dll_Pll_Tracking_fpga_sc", gr::io_signature::make(0, 0, sizeof(lv_16sc_t)),
+ gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
+{
+ // Telemetry bit synchronization message port input
+ this->message_port_register_out(pmt::mp("events"));
+
+ // initialize internal vars
+ d_dump = dump;
+ d_if_freq = if_freq;
+ d_fs_in = fs_in;
+ d_vector_length = vector_length;
+ d_dump_filename = dump_filename;
+ d_current_prn_length_samples = static_cast(d_vector_length);
+ d_correlation_length_samples = static_cast(d_vector_length);
+
+ // Initialize tracking ==========================================
+ d_code_loop_filter.set_DLL_BW(dll_bw_hz);
+ d_carrier_loop_filter.set_PLL_BW(pll_bw_hz);
+
+ //--- DLL variables --------------------------------------------------------
+ d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips)
+
+ // Initialization of local code replica
+ // Get space for a vector with the C/A code replica sampled 1x/chip
+ //d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment()));
+ //d_ca_code_16sc = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment()));
+ //d_ca_code_16sc = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(int), volk_gnsssdr_get_alignment()));
+
+ // correlator outputs (scalar)
+ d_n_correlator_taps = 3; // Early, Prompt, and Late
+ d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
+ for (int n = 0; n < d_n_correlator_taps; n++)
+ {
+ d_correlator_outs[n] = gr_complex(0, 0);
+ }
+ d_local_code_shift_chips = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(float), volk_gnsssdr_get_alignment()));
+
+ // Set TAPs delay values [chips]
+ d_local_code_shift_chips[0] = -d_early_late_spc_chips;
+ d_local_code_shift_chips[1] = 0.0;
+ d_local_code_shift_chips[2] = d_early_late_spc_chips;
+
+ // create multicorrelator class
+ multicorrelator_fpga_8sc = std::make_shared(d_n_correlator_taps, device_name, device_base);
+
+ //--- Perform initializations ------------------------------
+ // define initial code frequency basis of NCO
+ d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ;
+ // define residual code phase (in chips)
+ d_rem_code_phase_samples = 0.0;
+ // define residual carrier phase
+ d_rem_carr_phase_rad = 0.0;
+
+ // sample synchronization
+ d_sample_counter = 0;
+ d_acq_sample_stamp = 0;
+
+ d_enable_tracking = false;
+ d_pull_in = false;
+
+ // CN0 estimation and lock detector buffers
+ d_cn0_estimation_counter = 0;
+ d_Prompt_buffer = new gr_complex[FLAGS_cn0_samples];
+ d_carrier_lock_test = 1;
+ d_CN0_SNV_dB_Hz = 0;
+ d_carrier_lock_fail_counter = 0;
+ d_carrier_lock_threshold = FLAGS_carrier_lock_th;
+
+ systemName["G"] = std::string("GPS");
+ systemName["S"] = std::string("SBAS");
+
+ d_acquisition_gnss_synchro = 0;
+ d_channel = 0;
+ d_acq_code_phase_samples = 0.0;
+ d_acq_carrier_doppler_hz = 0.0;
+ d_carrier_doppler_hz = 0.0;
+ d_acc_carrier_phase_rad = 0.0;
+ d_code_phase_samples = 0.0;
+ d_rem_code_phase_chips = 0.0;
+ d_code_phase_step_chips = 0.0;
+ d_carrier_phase_step_rad = 0.0;
+
+ set_relative_rate(1.0 / static_cast(d_vector_length));
+
+ multicorrelator_fpga_8sc->set_output_vectors(d_correlator_outs);
+}
+
+
+void Gps_L1_Ca_Dll_Pll_Tracking_fpga_sc::start_tracking()
+{
+ /*
+ * correct the code phase according to the delay between acq and trk
+ */
+ //printf("TRK : start tracking for satellite %d\n", d_acquisition_gnss_synchro->PRN);
+ d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples;
+ d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz;
+ d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples;
+ long int acq_trk_diff_samples;
+ double acq_trk_diff_seconds;
+ acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length;
+ DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples;
+ acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in);
+ // Doppler effect
+ // Fd=(C/(C+Vr))*F
+ double radial_velocity = (GPS_L1_FREQ_HZ + d_acq_carrier_doppler_hz) / GPS_L1_FREQ_HZ;
+ // new chip and prn sequence periods based on acq Doppler
+ double T_chip_mod_seconds;
+ double T_prn_mod_seconds;
+ double T_prn_mod_samples;
+ d_code_freq_chips = radial_velocity * GPS_L1_CA_CODE_RATE_HZ;
+ d_code_phase_step_chips = static_cast(d_code_freq_chips) / static_cast(d_fs_in);
+ T_chip_mod_seconds = 1 / d_code_freq_chips;
+ T_prn_mod_seconds = T_chip_mod_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
+ T_prn_mod_samples = T_prn_mod_seconds * static_cast(d_fs_in);
+ d_current_prn_length_samples = round(T_prn_mod_samples);
+ double T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ;
+ double T_prn_true_samples = T_prn_true_seconds * static_cast(d_fs_in);
+ double T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds;
+ double N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds;
+ double corrected_acq_phase_samples, delay_correction_samples;
+ corrected_acq_phase_samples = fmod((d_acq_code_phase_samples + T_prn_diff_seconds * N_prn_diff * static_cast(d_fs_in)), T_prn_true_samples);
+ if (corrected_acq_phase_samples < 0)
+ {
+ corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples;
+ }
+ delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples;
+ d_acq_code_phase_samples = corrected_acq_phase_samples;
+ d_carrier_doppler_hz = d_acq_carrier_doppler_hz;
+ d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in);
+ // DLL/PLL filter initialization
+ d_carrier_loop_filter.initialize(); // initialize the carrier filter
+ d_code_loop_filter.initialize(); // initialize the code filter
+ // generate local reference ALWAYS starting at chip 1 (1 sample per chip)
+ //gps_l1_ca_code_gen_float(d_ca_code, d_acquisition_gnss_synchro->PRN, 0);
+ //gps_l1_ca_code_gen_int(d_ca_code_16sc, d_acquisition_gnss_synchro->PRN, 0);
+ /* for (int n = 0; n < static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS); n++)
+ {
+ d_ca_code_16sc[n] = d_ca_code[n];
+ } */
+ //multicorrelator_fpga_8sc->set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code_16sc, d_local_code_shift_chips, d_acquisition_gnss_synchro->PRN);
+ multicorrelator_fpga_8sc->set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_local_code_shift_chips, d_acquisition_gnss_synchro->PRN);
+ for (int n = 0; n < d_n_correlator_taps; n++)
+ {
+ d_correlator_outs[n] = gr_complex(0, 0);
+ }
+ d_carrier_lock_fail_counter = 0;
+ d_rem_code_phase_samples = 0;
+ d_rem_carr_phase_rad = 0.0;
+ d_rem_code_phase_chips = 0.0;
+ d_acc_carrier_phase_rad = 0.0;
+ d_code_phase_samples = d_acq_code_phase_samples;
+ std::string sys_ = &d_acquisition_gnss_synchro->System;
+ sys = sys_.substr(0, 1);
+ std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl;
+ LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel;
+ // enable tracking
+ d_pull_in = true;
+ d_enable_tracking = true; //do it in the end to avoid starting running tracking before finishing this function
+ LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz
+ << " Code Phase correction [samples]=" << delay_correction_samples
+ << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples;
+}
+
+
+Gps_L1_Ca_Dll_Pll_Tracking_fpga_sc::~Gps_L1_Ca_Dll_Pll_Tracking_fpga_sc()
+{
+ if (d_dump_file.is_open())
+ {
+ try
+ {
+ d_dump_file.close();
+ }
+ catch (const std::exception &ex)
+ {
+ LOG(WARNING) << "Exception in destructor " << ex.what();
+ }
+ }
+ try
+ {
+ volk_gnsssdr_free(d_local_code_shift_chips);
+ volk_gnsssdr_free(d_correlator_outs);
+ delete[] d_Prompt_buffer;
+ multicorrelator_fpga_8sc->free();
+ }
+ catch (const std::exception &ex)
+ {
+ LOG(WARNING) << "Exception in destructor " << ex.what();
+ }
+}
+
+
+int Gps_L1_Ca_Dll_Pll_Tracking_fpga_sc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
+ gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
+{
+ unsigned absolute_samples_offset;
+ // process vars
+ double carr_error_hz = 0.0;
+ double carr_error_filt_hz = 0.0;
+ double code_error_chips = 0.0;
+ double code_error_filt_chips = 0.0;
+
+ int next_prn_length_samples = d_current_prn_length_samples;
+
+ // Block input data and block output stream pointers
+ Gnss_Synchro **out = reinterpret_cast(&output_items[0]);
+
+ // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder
+ Gnss_Synchro current_synchro_data = Gnss_Synchro();
+
+ if (d_enable_tracking == true)
+ {
+ // Fill the acquisition data
+ current_synchro_data = *d_acquisition_gnss_synchro;
+ // Receiver signal alignment
+ if (d_pull_in == true)
+ {
+ d_pull_in = false;
+ multicorrelator_fpga_8sc->lock_channel();
+ unsigned counter_value = multicorrelator_fpga_8sc->read_sample_counter();
+ unsigned num_frames = ceil((counter_value - current_synchro_data.Acq_samplestamp_samples - current_synchro_data.Acq_delay_samples) / d_correlation_length_samples);
+ absolute_samples_offset = current_synchro_data.Acq_delay_samples + current_synchro_data.Acq_samplestamp_samples + num_frames * d_correlation_length_samples;
+ multicorrelator_fpga_8sc->set_initial_sample(absolute_samples_offset);
+ d_sample_counter = absolute_samples_offset;
+ current_synchro_data.Tracking_sample_counter = absolute_samples_offset;
+ }
+ else
+ {
+ // continue as from the previous point
+ d_sample_counter = d_sample_counter_next;
+ }
+ d_sample_counter_next = d_sample_counter + d_current_prn_length_samples;
+
+ // ################# CARRIER WIPEOFF AND CORRELATORS ##############################
+ // perform carrier wipe-off and compute Early, Prompt and Late correlation
+ multicorrelator_fpga_8sc->Carrier_wipeoff_multicorrelator_resampler(
+ d_rem_carr_phase_rad, d_carrier_phase_step_rad,
+ d_rem_code_phase_chips, d_code_phase_step_chips,
+ d_current_prn_length_samples);
+
+ // ################## PLL ##########################################################
+ // PLL discriminator
+ // Update PLL discriminator [rads/Ti -> Secs/Ti]
+ carr_error_hz = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / GPS_TWO_PI; // prompt output
+ // Carrier discriminator filter
+ carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(carr_error_hz);
+ // New carrier Doppler frequency estimation
+ d_carrier_doppler_hz = d_acq_carrier_doppler_hz + carr_error_filt_hz;
+ // New code Doppler frequency estimation
+ d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ);
+
+ // ################## DLL ##########################################################
+ // DLL discriminator
+ code_error_chips = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); // [chips/Ti] //early and late
+ // Code discriminator filter
+ code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); // [chips/second]
+ double T_chip_seconds = 1.0 / static_cast(d_code_freq_chips);
+ double T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
+ double code_error_filt_secs = (T_prn_seconds * code_error_filt_chips * T_chip_seconds); //[seconds]
+
+ // ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
+ // keep alignment parameters for the next input buffer
+ // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
+ double T_prn_samples = T_prn_seconds * static_cast(d_fs_in);
+ double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in);
+ next_prn_length_samples = round(K_blk_samples);
+
+ //################### PLL COMMANDS #################################################
+ // carrier phase step (NCO phase increment per sample) [rads/sample]
+ d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in);
+ // remnant carrier phase to prevent overflow in the code NCO
+ d_rem_carr_phase_rad = d_rem_carr_phase_rad + d_carrier_phase_step_rad * d_current_prn_length_samples;
+ d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, GPS_TWO_PI);
+ // carrier phase accumulator
+ d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * d_current_prn_length_samples;
+
+ //################### DLL COMMANDS #################################################
+ // code phase step (Code resampler phase increment per sample) [chips/sample]
+ d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in);
+ // remnant code phase [chips]
+ d_rem_code_phase_samples = K_blk_samples - next_prn_length_samples; // rounding error < 1 sample
+ d_rem_code_phase_chips = d_code_freq_chips * (d_rem_code_phase_samples / static_cast(d_fs_in));
+
+ // ####### CN0 ESTIMATION AND LOCK DETECTORS ######
+ if (d_cn0_estimation_counter < FLAGS_cn0_samples)
+ {
+ // fill buffer with prompt correlator output values
+ d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; //prompt
+ d_cn0_estimation_counter++;
+ }
+ else
+ {
+ d_cn0_estimation_counter = 0;
+ // Code lock indicator
+ d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, FLAGS_cn0_samples, GPS_L1_CA_CODE_PERIOD);
+ // Carrier lock indicator
+ d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, FLAGS_cn0_samples);
+ // Loss of lock detection
+ if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min)
+ {
+ d_carrier_lock_fail_counter++;
+ }
+ else
+ {
+ if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--;
+ }
+ if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail)
+ {
+ std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
+ LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
+ this->message_port_pub(pmt::mp("events"), pmt::from_long(3)); // 3 -> loss of lock
+ d_carrier_lock_fail_counter = 0;
+ d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
+ multicorrelator_fpga_8sc->unlock_channel();
+ }
+ }
+
+ // ########### Output the tracking data to navigation and PVT ##########
+ current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real());
+ current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag());
+ current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples;
+ current_synchro_data.Code_phase_samples = d_rem_code_phase_samples;
+ current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad;
+ current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
+ current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
+ current_synchro_data.Flag_valid_symbol_output = true;
+ current_synchro_data.correlation_length_ms = 1;
+ }
+ else
+ {
+ for (int n = 0; n < d_n_correlator_taps; n++)
+ {
+ d_correlator_outs[n] = gr_complex(0, 0);
+ }
+
+ current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples;
+ current_synchro_data.System = {'G'};
+ current_synchro_data.correlation_length_ms = 1;
+ }
+
+ //assign the GNURadio block output data
+ current_synchro_data.fs = d_fs_in;
+ *out[0] = current_synchro_data;
+ if (d_enable_tracking == true) // in the FPGA case dump data only when tracking is enabled, otherwise the dumped data is useless
+ {
+ if (d_dump)
+ {
+ // MULTIPLEXED FILE RECORDING - Record results to file
+ float prompt_I;
+ float prompt_Q;
+ float tmp_E, tmp_P, tmp_L;
+ double tmp_double;
+ unsigned long int tmp_long;
+ prompt_I = d_correlator_outs[1].real();
+ prompt_Q = d_correlator_outs[1].imag();
+ tmp_E = std::abs(d_correlator_outs[0]);
+ tmp_P = std::abs(d_correlator_outs[1]);
+ tmp_L = std::abs(d_correlator_outs[2]);
+ try
+ {
+ // EPR
+ d_dump_file.write(reinterpret_cast(&tmp_E), sizeof(float));
+ d_dump_file.write(reinterpret_cast(&tmp_P), sizeof(float));
+ d_dump_file.write(reinterpret_cast(&tmp_L), sizeof(float));
+ // PROMPT I and Q (to analyze navigation symbols)
+ d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float));
+ d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float));
+ // PRN start sample stamp
+ tmp_long = d_sample_counter + d_current_prn_length_samples;
+ d_dump_file.write(reinterpret_cast(&tmp_long), sizeof(unsigned long int));
+ // accumulated carrier phase
+ d_dump_file.write(reinterpret_cast(&d_acc_carrier_phase_rad), sizeof(double));
+
+ // carrier and code frequency
+ d_dump_file.write(reinterpret_cast(&d_carrier_doppler_hz), sizeof(double));
+ d_dump_file.write(reinterpret_cast(&d_code_freq_chips), sizeof(double));
+
+ // PLL commands
+ d_dump_file.write(reinterpret_cast(&carr_error_hz), sizeof(double));
+ d_dump_file.write(reinterpret_cast(&carr_error_filt_hz), sizeof(double));
+
+ // DLL commands
+ d_dump_file.write(reinterpret_cast(&code_error_chips), sizeof(double));
+ d_dump_file.write(reinterpret_cast(&code_error_filt_chips), sizeof(double));
+
+ // CN0 and carrier lock test
+ d_dump_file.write(reinterpret_cast(&d_CN0_SNV_dB_Hz), sizeof(double));
+ d_dump_file.write(reinterpret_cast(&d_carrier_lock_test), sizeof(double));
+
+ // AUX vars (for debug purposes)
+ tmp_double = d_rem_code_phase_samples;
+ d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double));
+ tmp_double = static_cast(d_sample_counter);
+ d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double));
+
+ // PRN
+ unsigned int prn_ = d_acquisition_gnss_synchro->PRN;
+ d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int));
+ }
+ catch (const std::ifstream::failure &e)
+ {
+ LOG(WARNING) << "Exception writing trk dump file " << e.what();
+ }
+ }
+ }
+
+
+ d_current_prn_length_samples = next_prn_length_samples;
+ d_sample_counter += d_current_prn_length_samples; // count for the processed samples
+
+ if (d_enable_tracking == true)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+void Gps_L1_Ca_Dll_Pll_Tracking_fpga_sc::set_channel(unsigned int channel)
+{
+ d_channel = channel;
+ multicorrelator_fpga_8sc->set_channel(d_channel);
+ LOG(INFO) << "Tracking Channel set to " << d_channel;
+
+ // ############# ENABLE DATA FILE LOG #################
+ if (d_dump == true)
+ {
+ if (d_dump_file.is_open() == false)
+ {
+ try
+ {
+ d_dump_filename.append(boost::lexical_cast(d_channel));
+ d_dump_filename.append(".dat");
+ d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
+ d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
+ LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str();
+ }
+ catch (const std::ifstream::failure &e)
+ {
+ LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what();
+ }
+ }
+ }
+}
+
+
+void Gps_L1_Ca_Dll_Pll_Tracking_fpga_sc::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro)
+{
+ d_acquisition_gnss_synchro = p_gnss_synchro;
+}
+
+
+void Gps_L1_Ca_Dll_Pll_Tracking_fpga_sc::reset(void)
+{
+ multicorrelator_fpga_8sc->unlock_channel();
+}
diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_fpga_sc.h
similarity index 54%
rename from src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h
rename to src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_fpga_sc.h
index 1bd8bb0c1..295c3f177 100644
--- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h
+++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_fpga_sc.h
@@ -1,9 +1,9 @@
/*!
- * \file gps_l1_ca_dll_pll_c_aid_tracking_fpga_sc.h
+ * \file gps_l1_ca_dll_pll_tracking_cc.h
* \brief Interface of a code DLL + carrier PLL tracking block
- * \author Marc Majoral, 2017. mmajoral(at)cttc.cat
- * Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
+ * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
* Javier Arribas, 2011. jarribas(at)cttc.es
+ * 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,
@@ -12,7 +12,7 @@
*
* -------------------------------------------------------------------------
*
- * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
+ * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@@ -35,13 +35,14 @@
* -------------------------------------------------------------------------
*/
-#ifndef GNSS_SDR_GPS_L1_CA_DLL_PLL_C_AID_TRACKING_FPGA_SC_H
-#define GNSS_SDR_GPS_L1_CA_DLL_PLL_C_AID_TRACKING_FPGA_SC_H
+#ifndef GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_SC_H
+#define GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_SC_H
+
#include "gps_sdr_signal_processing.h"
#include "gnss_synchro.h"
#include "tracking_2nd_DLL_filter.h"
-#include "tracking_FLL_PLL_filter.h"
+#include "tracking_2nd_PLL_filter.h"
#include "fpga_multicorrelator_8sc.h"
#include
#include
@@ -51,47 +52,62 @@
#include