mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	Merge branch 'fpga' of https://github.com/mmajoral/gnss-sdr into merge-marc
This commit is contained in:
		| @@ -19,3 +19,4 @@ | ||||
| add_subdirectory(adapters) | ||||
| add_subdirectory(gnuradio_blocks) | ||||
| add_subdirectory(libs) | ||||
|  | ||||
|   | ||||
| @@ -37,7 +37,7 @@ set(ACQ_ADAPTER_SOURCES | ||||
| ) | ||||
|  | ||||
| if(ENABLE_FPGA) | ||||
|     set(ACQ_ADAPTER_SOURCES ${ACQ_ADAPTER_SOURCES} gps_l1_ca_pcps_acquisition_fpga.cc) | ||||
|     set(ACQ_ADAPTER_SOURCES ${ACQ_ADAPTER_SOURCES} gps_l1_ca_pcps_acquisition_fpga.cc gps_l2_m_pcps_acquisition_fpga.cc galileo_e1_pcps_ambiguous_acquisition_fpga.cc galileo_e5a_pcps_acquisition_fpga.cc gps_l5i_pcps_acquisition_fpga.cc) | ||||
| endif(ENABLE_FPGA) | ||||
|      | ||||
| if(OPENCL_FOUND) | ||||
|   | ||||
| @@ -0,0 +1,552 @@ | ||||
| /*! | ||||
|  * \file galileo_e1_pcps_ambiguous_acquisition.cc | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  Galileo E1 Signals | ||||
|  * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "galileo_e1_pcps_ambiguous_acquisition_fpga.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "galileo_e1_signal_processing.h" | ||||
| #include "Galileo_E1.h" | ||||
| #include "gnss_sdr_flags.h" | ||||
| #include <boost/lexical_cast.hpp> | ||||
| #include <boost/math/distributions/exponential.hpp> | ||||
| #include <glog/logging.h> | ||||
|  | ||||
|  | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( | ||||
|     ConfigurationInterface* configuration, std::string role, | ||||
|     unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) | ||||
| { | ||||
|     //printf("top acq constructor start\n"); | ||||
|     pcpsconf_fpga_t acq_parameters; | ||||
|     configuration_ = configuration; | ||||
|     std::string default_item_type = "gr_complex"; | ||||
|     std::string default_dump_filename = "./data/acquisition.dat"; | ||||
|  | ||||
|     DLOG(INFO) << "role " << role; | ||||
|  | ||||
| //    item_type_ = configuration_->property(role + ".item_type", default_item_type); | ||||
|  | ||||
|     long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); | ||||
|     long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|     acq_parameters.fs_in = fs_in; | ||||
|     //if_ = configuration_->property(role + ".if", 0); | ||||
|     //acq_parameters.freq = if_; | ||||
|  | ||||
|   //  dump_ = configuration_->property(role + ".dump", false); | ||||
|   //  acq_parameters.dump = dump_; | ||||
|   //  blocking_ = configuration_->property(role + ".blocking", true); | ||||
| //    acq_parameters.blocking = blocking_; | ||||
|     doppler_max_ = configuration_->property(role + ".doppler_max", 5000); | ||||
|     if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; | ||||
|     acq_parameters.doppler_max = doppler_max_; | ||||
|     //unsigned int sampled_ms = 4; | ||||
|     //acq_parameters.sampled_ms = sampled_ms; | ||||
|     unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 4); | ||||
|     acq_parameters.sampled_ms = sampled_ms; | ||||
|  | ||||
|  //   bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); | ||||
|  //   acq_parameters.bit_transition_flag = bit_transition_flag_; | ||||
|  //   use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true);  //will be false in future versions | ||||
|  //   acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; | ||||
|     acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false);  //will be true in future versions | ||||
|  | ||||
|  //   max_dwells_ = configuration_->property(role + ".max_dwells", 1); | ||||
|  //   acq_parameters.max_dwells = max_dwells_; | ||||
|  //   dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); | ||||
|  //   acq_parameters.dump_filename = dump_filename_; | ||||
|     //--- Find number of samples per spreading code (4 ms)  ----------------- | ||||
|     unsigned int code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); | ||||
|     //acq_parameters.samples_per_code = code_length_; | ||||
|     //int samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001)); | ||||
|     //acq_parameters.samples_per_ms = samples_per_ms; | ||||
|     //unsigned int vector_length = sampled_ms * samples_per_ms; | ||||
|  | ||||
| //    if (bit_transition_flag_) | ||||
| //        { | ||||
| //            vector_length_ *= 2; | ||||
| //        } | ||||
|  | ||||
|     //printf("fs_in = %d\n", fs_in); | ||||
|     //printf("Galileo_E1_B_CODE_LENGTH_CHIPS = %f\n", Galileo_E1_B_CODE_LENGTH_CHIPS); | ||||
|     //printf("Galileo_E1_CODE_CHIP_RATE_HZ = %f\n", Galileo_E1_CODE_CHIP_RATE_HZ); | ||||
|     //printf("acq adapter code_length = %d\n", code_length); | ||||
|     acq_parameters.code_length = code_length; | ||||
|     // 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; | ||||
|     //printf("acq adapter nsamples_total (= vector_length) = %d\n", vector_length); | ||||
|     unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0); | ||||
|     acq_parameters.select_queue_Fpga = select_queue_Fpga; | ||||
|     std::string default_device_name = "/dev/uio0"; | ||||
|     std::string device_name = configuration_->property(role + ".devicename", default_device_name); | ||||
|     acq_parameters.device_name = device_name; | ||||
|     acq_parameters.samples_per_ms = nsamples_total/sampled_ms; | ||||
|     acq_parameters.samples_per_code = nsamples_total; | ||||
|  | ||||
|     // compute all the GALILEO E1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time | ||||
|     // a channel is assigned) | ||||
|     gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(nsamples_total, true);  // Direct FFT | ||||
|     std::complex<float>* code = new std::complex<float>[nsamples_total];  // buffer for the local code | ||||
|     gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||
|     d_all_fft_codes_ = new lv_16sc_t[nsamples_total * Galileo_E1_NUMBER_OF_CODES];  // memory containing all the possible fft codes for PRN 0 to 32 | ||||
|     float max;                                                        // temporary maxima search | ||||
|  | ||||
|     //int tmp_re, tmp_im; | ||||
|  | ||||
|     for (unsigned int PRN = 1; PRN <= Galileo_E1_NUMBER_OF_CODES; PRN++) | ||||
|         { | ||||
|  | ||||
|         //code_ = new gr_complex[vector_length_]; | ||||
|  | ||||
|         bool cboc = false; // cboc is set to 0 when using the FPGA | ||||
|  | ||||
|         //std::complex<float>* code = new std::complex<float>[code_length_]; | ||||
|  | ||||
|         if (acquire_pilot_ == true) | ||||
|             { | ||||
|                 //printf("yes acquiring pilot!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1\n"); | ||||
|                 //set local signal generator to Galileo E1 pilot component (1C) | ||||
|                 char pilot_signal[3] = "1C"; | ||||
|                 galileo_e1_code_gen_complex_sampled(code, pilot_signal, | ||||
|                     cboc, PRN, fs_in, 0, false); | ||||
|             } | ||||
|         else | ||||
|             { | ||||
|                 char data_signal[3] = "1B"; | ||||
|                 galileo_e1_code_gen_complex_sampled(code, data_signal, | ||||
|                     cboc, PRN, fs_in, 0, false); | ||||
|             } | ||||
|  | ||||
| //        for (unsigned int i = 0; i < sampled_ms / 4; i++) | ||||
| //            { | ||||
| //                //memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_); | ||||
| //                memcpy(&(d_all_fft_codes_[i * code_length_]), code, sizeof(gr_complex) * code_length_); | ||||
| //            } | ||||
|  | ||||
|  | ||||
| //                // debug | ||||
| //                char filename[25]; | ||||
| //                FILE *fid; | ||||
| //                sprintf(filename,"gal_prn%d.txt", PRN); | ||||
| //                fid = fopen(filename, "w"); | ||||
| //                for (unsigned int kk=0;kk< nsamples_total; kk++) | ||||
| //                    { | ||||
| //                        fprintf(fid, "%f\n", code[kk].real()); | ||||
| //                        fprintf(fid, "%f\n", code[kk].imag()); | ||||
| //                    } | ||||
| //                fclose(fid); | ||||
|  | ||||
|  | ||||
| //        // fill in zero padding | ||||
|         for (int s = code_length; s < nsamples_total; s++) | ||||
|             { | ||||
|                 code[s] = std::complex<float>(static_cast<float>(0,0)); | ||||
|                 //code[s] = 0; | ||||
|             } | ||||
|  | ||||
|         memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total);   // copy to FFT buffer | ||||
|         fft_if->execute();                                                                 // Run the FFT of local code | ||||
|         volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total);  // conjugate values | ||||
|  | ||||
| //        // debug | ||||
| //        char filename[25]; | ||||
| //        FILE *fid; | ||||
| //        sprintf(filename,"fft_gal_prn%d.txt", PRN); | ||||
| //        fid = fopen(filename, "w"); | ||||
| //        for (unsigned int kk=0;kk< nsamples_total; kk++) | ||||
| //            { | ||||
| //                fprintf(fid, "%f\n", fft_codes_padded[kk].real()); | ||||
| //                fprintf(fid, "%f\n", fft_codes_padded[kk].imag()); | ||||
| //            } | ||||
| //        fclose(fid); | ||||
|  | ||||
|  | ||||
|         // normalize the code | ||||
|         max = 0;                                                                           // initialize maximum value | ||||
|         for (unsigned int i = 0; i < nsamples_total; i++)                                  // search for maxima | ||||
|             { | ||||
|                 if (std::abs(fft_codes_padded[i].real()) > max) | ||||
|                     { | ||||
|                         max = std::abs(fft_codes_padded[i].real()); | ||||
|                     } | ||||
|                 if (std::abs(fft_codes_padded[i].imag()) > max) | ||||
|                     { | ||||
|                         max = std::abs(fft_codes_padded[i].imag()); | ||||
|                     } | ||||
|             } | ||||
|         for (unsigned int i = 0; i < nsamples_total; i++)  // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs | ||||
|             { | ||||
|                 //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(4096*fft_codes_padded[i].real() * (pow(2, 3) - 1) / max)), | ||||
|                 //    static_cast<int>(floor(4096*fft_codes_padded[i].imag() * (pow(2, 3) - 1) / max))); | ||||
| //                d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(1024*fft_codes_padded[i].real() * (pow(2, 5) - 1) / max)), | ||||
| //                    static_cast<int>(floor(1024*fft_codes_padded[i].imag() * (pow(2, 5) - 1) / max))); | ||||
|  //               d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), | ||||
|  //                   static_cast<int>(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); | ||||
| //                d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(16*fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)), | ||||
| //                    static_cast<int>(floor(16*fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max))); | ||||
|                 d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), | ||||
|                     static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); | ||||
|  | ||||
| //                tmp_re = static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)); | ||||
| //                tmp_im = static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max)); | ||||
|  | ||||
| //                if (tmp_re > 127) | ||||
| //                    { | ||||
| //                        tmp_re = 127; | ||||
| //                    } | ||||
| //                if (tmp_re < -128) | ||||
| //                    { | ||||
| //                        tmp_re = -128; | ||||
| //                    } | ||||
| //                if (tmp_im > 127) | ||||
| //                    { | ||||
| //                        tmp_im = 127; | ||||
| //                    } | ||||
| //                if (tmp_im < -128) | ||||
| //                    { | ||||
| //                        tmp_im = -128; | ||||
| //                    } | ||||
| //                d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(tmp_re), static_cast<int>(tmp_im)); | ||||
| // | ||||
|             } | ||||
|  | ||||
| //        // debug | ||||
| //        char filename2[25]; | ||||
| //        FILE *fid2; | ||||
| //        sprintf(filename2,"fft_gal_prn%d_norm.txt", PRN); | ||||
| //        fid2 = fopen(filename2, "w"); | ||||
| //        for (unsigned int kk=0;kk< nsamples_total; kk++) | ||||
| //            { | ||||
| //                fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real()); | ||||
| //                fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag()); | ||||
| //            } | ||||
| //        fclose(fid2); | ||||
|  | ||||
|  | ||||
|         } | ||||
|  | ||||
|  | ||||
| //    for (unsigned int PRN = 1; PRN <= Galileo_E1_NUMBER_OF_CODES; PRN++) | ||||
| //        { | ||||
| //                    // debug | ||||
| //                    char filename2[25]; | ||||
| //                    FILE *fid2; | ||||
| //                    sprintf(filename2,"fft_gal_prn%d_norm_last.txt", PRN); | ||||
| //                    fid2 = fopen(filename2, "w"); | ||||
| //                    for (unsigned int kk=0;kk< nsamples_total; kk++) | ||||
| //                        { | ||||
| //                            fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real()); | ||||
| //                            fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag()); | ||||
| //                        } | ||||
| //                    fclose(fid2); | ||||
| //        } | ||||
|  | ||||
|     //acq_parameters | ||||
|  | ||||
|     acq_parameters.all_fft_codes = d_all_fft_codes_; | ||||
|  | ||||
|     // temporary buffers that we can delete | ||||
|     delete[] code; | ||||
|     delete fft_if; | ||||
|     delete[] fft_codes_padded; | ||||
|  | ||||
|     acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
| //    stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); | ||||
| //    DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; | ||||
|  | ||||
| //    if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); | ||||
| //            float_to_complex_ = gr::blocks::float_to_complex::make(); | ||||
| //        } | ||||
|  | ||||
|     channel_ = 0; | ||||
|     //threshold_ = 0.0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = 0; | ||||
|     //printf("top acq constructor end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| GalileoE1PcpsAmbiguousAcquisitionFpga::~GalileoE1PcpsAmbiguousAcquisitionFpga() | ||||
| { | ||||
|     //printf("top acq destructor start\n"); | ||||
|     //delete[] code_; | ||||
|     delete[] d_all_fft_codes_; | ||||
|     //printf("top acq destructor end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::set_channel(unsigned int channel) | ||||
| { | ||||
|     //printf("top acq set channel start\n"); | ||||
|     channel_ = channel; | ||||
|     acquisition_fpga_->set_channel(channel_); | ||||
|     //printf("top acq set channel end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::set_threshold(float threshold) | ||||
| { | ||||
|     //printf("top acq set threshold start\n"); | ||||
|     // the .pfa parameter and the threshold calculation is only used for the CFAR algorithm. | ||||
|     // We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such. | ||||
|  | ||||
| //    float pfa = configuration_->property(role_ + boost::lexical_cast<std::string>(channel_) + ".pfa", 0.0); | ||||
| // | ||||
| //    if (pfa == 0.0) pfa = configuration_->property(role_ + ".pfa", 0.0); | ||||
| // | ||||
| //    if (pfa == 0.0) | ||||
| //        { | ||||
| //            threshold_ = threshold; | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            threshold_ = calculate_threshold(pfa); | ||||
| //        } | ||||
|  | ||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; | ||||
|     acquisition_fpga_->set_threshold(threshold); | ||||
| //    acquisition_fpga_->set_threshold(threshold_); | ||||
|     //printf("top acq set threshold end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_max(unsigned int doppler_max) | ||||
| { | ||||
|     //printf("top acq set doppler max start\n"); | ||||
|     doppler_max_ = doppler_max; | ||||
|  | ||||
|     acquisition_fpga_->set_doppler_max(doppler_max_); | ||||
|     //printf("top acq set doppler max end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_step(unsigned int doppler_step) | ||||
| { | ||||
|     //printf("top acq set doppler step start\n"); | ||||
|     doppler_step_ = doppler_step; | ||||
|  | ||||
|     acquisition_fpga_->set_doppler_step(doppler_step_); | ||||
|     //printf("top acq set doppler step end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) | ||||
| { | ||||
|     //printf("top acq set gnss synchro start\n"); | ||||
|     gnss_synchro_ = gnss_synchro; | ||||
|  | ||||
|     acquisition_fpga_->set_gnss_synchro(gnss_synchro_); | ||||
|     //printf("top acq set gnss synchro end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| signed int GalileoE1PcpsAmbiguousAcquisitionFpga::mag() | ||||
| { | ||||
|    // printf("top acq mag start\n"); | ||||
|     return acquisition_fpga_->mag(); | ||||
|     //printf("top acq mag end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::init() | ||||
| { | ||||
|    // printf("top acq init start\n"); | ||||
|     acquisition_fpga_->init(); | ||||
|    // printf("top acq init end\n"); | ||||
|     //set_local_code(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::set_local_code() | ||||
| { | ||||
|    // printf("top acq set local code start\n"); | ||||
| //    bool cboc = configuration_->property( | ||||
| //        "Acquisition" + boost::lexical_cast<std::string>(channel_) + ".cboc", false); | ||||
| // | ||||
| //    std::complex<float>* code = new std::complex<float>[code_length_]; | ||||
| // | ||||
| //    if (acquire_pilot_ == true) | ||||
| //        { | ||||
| //            //set local signal generator to Galileo E1 pilot component (1C) | ||||
| //            char pilot_signal[3] = "1C"; | ||||
| //            galileo_e1_code_gen_complex_sampled(code, pilot_signal, | ||||
| //                cboc, gnss_synchro_->PRN, fs_in_, 0, false); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, | ||||
| //                cboc, gnss_synchro_->PRN, fs_in_, 0, false); | ||||
| //        } | ||||
| // | ||||
| // | ||||
| //    for (unsigned int i = 0; i < sampled_ms_ / 4; i++) | ||||
| //        { | ||||
| //            memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_); | ||||
| //        } | ||||
|  | ||||
|     //acquisition_fpga_->set_local_code(code_); | ||||
|     acquisition_fpga_->set_local_code(); | ||||
| //    delete[] code; | ||||
|   //  printf("top acq set local code end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::reset() | ||||
| { | ||||
|  //   printf("top acq reset start\n"); | ||||
|     acquisition_fpga_->set_active(true); | ||||
|   //  printf("top acq reset end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::set_state(int state) | ||||
| { | ||||
|   //  printf("top acq set state start\n"); | ||||
|     acquisition_fpga_->set_state(state); | ||||
|   //  printf("top acq set state end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| //float GalileoE1PcpsAmbiguousAcquisitionFpga::calculate_threshold(float pfa) | ||||
| //{ | ||||
| //    unsigned int frequency_bins = 0; | ||||
| //    for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_) | ||||
| //        { | ||||
| //            frequency_bins++; | ||||
| //        } | ||||
| // | ||||
| //    DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; | ||||
| // | ||||
| //    unsigned int ncells = vector_length_ * frequency_bins; | ||||
| //    double exponent = 1 / static_cast<double>(ncells); | ||||
| //    double val = pow(1.0 - pfa, exponent); | ||||
| //    double lambda = double(vector_length_); | ||||
| //    boost::math::exponential_distribution<double> mydist(lambda); | ||||
| //    float threshold = static_cast<float>(quantile(mydist, val)); | ||||
| // | ||||
| //    return threshold; | ||||
| //} | ||||
|  | ||||
|  | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
|   //  printf("top acq connect\n"); | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); | ||||
| //            top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); | ||||
| //            top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); | ||||
| //            top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
| //        } | ||||
|  | ||||
|     // nothing to connect | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::disconnect(gr::top_block_sptr top_block) | ||||
| { | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            // Since a byte-based acq implementation is not available, | ||||
| //            // we just convert cshorts to gr_complex | ||||
| //            top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); | ||||
| //            top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); | ||||
| //            top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); | ||||
| //            top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
| //        } | ||||
|  | ||||
|     // nothing to disconnect | ||||
|  //   printf("top acq disconnect\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_left_block() | ||||
| { | ||||
|  //   printf("top acq get left block start\n"); | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            return stream_to_vector_; | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            return stream_to_vector_; | ||||
| //        } | ||||
| //    else if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            return cbyte_to_float_x2_; | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
|             return nullptr; | ||||
| //        } | ||||
|    //         printf("top acq get left block end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_right_block() | ||||
| { | ||||
|  //   printf("top acq get right block start\n"); | ||||
|     return acquisition_fpga_; | ||||
|  //   printf("top acq get right block end\n"); | ||||
| } | ||||
|  | ||||
| @@ -0,0 +1,175 @@ | ||||
| /*! | ||||
|  * \file galileo_e1_pcps_ambiguous_acquisition.h | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  Galileo E1 Signals | ||||
|  * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ | ||||
| #define GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ | ||||
|  | ||||
| #include "acquisition_interface.h" | ||||
| #include "gnss_synchro.h" | ||||
| #include "pcps_acquisition_fpga.h" | ||||
| #include "complex_byte_to_float_x2.h" | ||||
| #include <gnuradio/blocks/stream_to_vector.h> | ||||
| #include <gnuradio/blocks/float_to_complex.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr.h> | ||||
| #include <string> | ||||
|  | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| /*! | ||||
|  * \brief This class adapts a PCPS acquisition block to an | ||||
|  *  AcquisitionInterface for Galileo E1 Signals | ||||
|  */ | ||||
| class GalileoE1PcpsAmbiguousAcquisitionFpga : public AcquisitionInterface | ||||
| { | ||||
| public: | ||||
|     GalileoE1PcpsAmbiguousAcquisitionFpga(ConfigurationInterface* configuration, | ||||
|         std::string role, unsigned int in_streams, | ||||
|         unsigned int out_streams); | ||||
|  | ||||
|     virtual ~GalileoE1PcpsAmbiguousAcquisitionFpga(); | ||||
|  | ||||
|     inline std::string role() override | ||||
|     { | ||||
|         //   printf("top acq role\n"); | ||||
|         return role_; | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition" | ||||
|      */ | ||||
|     inline std::string implementation() override | ||||
|     { | ||||
|         //  printf("top acq implementation\n"); | ||||
|         return "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga"; | ||||
|     } | ||||
|  | ||||
|     size_t item_size() override | ||||
|     { | ||||
|         //   printf("top acq item size\n"); | ||||
|         size_t item_size = sizeof(lv_16sc_t); | ||||
|         return item_size; | ||||
|     } | ||||
|  | ||||
|     void connect(gr::top_block_sptr top_block) override; | ||||
|     void disconnect(gr::top_block_sptr top_block) override; | ||||
|     gr::basic_block_sptr get_left_block() override; | ||||
|     gr::basic_block_sptr get_right_block() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition/tracking common Gnss_Synchro object pointer | ||||
|      * to efficiently exchange synchronization data between acquisition and | ||||
|      *  tracking blocks | ||||
|      */ | ||||
|     void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition channel unique ID | ||||
|      */ | ||||
|     void set_channel(unsigned int channel) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set statistics threshold of PCPS algorithm | ||||
|      */ | ||||
|     void set_threshold(float threshold) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set maximum Doppler off grid search | ||||
|      */ | ||||
|     void set_doppler_max(unsigned int doppler_max) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set Doppler steps for the grid search | ||||
|      */ | ||||
|     void set_doppler_step(unsigned int doppler_step) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Initializes acquisition algorithm. | ||||
|      */ | ||||
|     void init() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Sets local code for Galileo E1 PCPS acquisition algorithm. | ||||
|      */ | ||||
|     void set_local_code() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns the maximum peak of grid search | ||||
|      */ | ||||
|     signed int mag() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Restart acquisition algorithm | ||||
|      */ | ||||
|     void reset() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief If state = 1, it forces the block to start acquiring from the first sample | ||||
|      */ | ||||
|     void set_state(int state) override; | ||||
|  | ||||
| private: | ||||
|     ConfigurationInterface* configuration_; | ||||
|     //pcps_acquisition_sptr acquisition_; | ||||
|     pcps_acquisition_fpga_sptr acquisition_fpga_; | ||||
|     gr::blocks::stream_to_vector::sptr stream_to_vector_; | ||||
|     gr::blocks::float_to_complex::sptr float_to_complex_; | ||||
|     complex_byte_to_float_x2_sptr cbyte_to_float_x2_; | ||||
|     // size_t item_size_; | ||||
|     // std::string item_type_; | ||||
|     //unsigned int vector_length_; | ||||
|     //unsigned int code_length_; | ||||
|     bool bit_transition_flag_; | ||||
|     bool use_CFAR_algorithm_flag_; | ||||
|     bool acquire_pilot_; | ||||
|     unsigned int channel_; | ||||
|     //float threshold_; | ||||
|     unsigned int doppler_max_; | ||||
|     unsigned int doppler_step_; | ||||
|     //unsigned int sampled_ms_; | ||||
|     unsigned int max_dwells_; | ||||
|     //long fs_in_; | ||||
|     //long if_; | ||||
|     bool dump_; | ||||
|     bool blocking_; | ||||
|     std::string dump_filename_; | ||||
|     //std::complex<float>* code_; | ||||
|     Gnss_Synchro* gnss_synchro_; | ||||
|     std::string role_; | ||||
|     unsigned int in_streams_; | ||||
|     unsigned int out_streams_; | ||||
|     //float calculate_threshold(float pfa); | ||||
|  | ||||
|     // extra for the FPGA | ||||
|     lv_16sc_t* d_all_fft_codes_;  // memory that contains all the code ffts | ||||
| }; | ||||
|  | ||||
| #endif /* GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ */ | ||||
| @@ -0,0 +1,405 @@ | ||||
| /*! | ||||
|  * \file galileo_e5a_pcps_acquisition.cc | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  Galileo E5a data and pilot Signals | ||||
|  * \author Antonio Ramos, 2018. antonio.ramos(at)cttc.es | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * 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 <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "galileo_e5a_pcps_acquisition_fpga.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "galileo_e5_signal_processing.h" | ||||
| #include "Galileo_E5a.h" | ||||
| #include "gnss_sdr_flags.h" | ||||
| #include <boost/lexical_cast.hpp> | ||||
| #include <boost/math/distributions/exponential.hpp> | ||||
| #include <glog/logging.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterface* configuration, | ||||
|     std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) | ||||
| { | ||||
| 	//printf("creating the E5A acquisition"); | ||||
|     pcpsconf_fpga_t acq_parameters; | ||||
|     configuration_ = configuration; | ||||
|     std::string default_item_type = "gr_complex"; | ||||
|     std::string default_dump_filename = "../data/acquisition.dat"; | ||||
|  | ||||
|     DLOG(INFO) << "Role " << role; | ||||
|  | ||||
|     //item_type_ = configuration_->property(role + ".item_type", default_item_type); | ||||
|  | ||||
|     long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000); | ||||
|     long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|     acq_parameters.fs_in = fs_in; | ||||
|     //acq_parameters.freq = 0; | ||||
|  | ||||
|  | ||||
|     //dump_ = configuration_->property(role + ".dump", false); | ||||
|     //acq_parameters.dump = dump_; | ||||
|     doppler_max_ = configuration_->property(role + ".doppler_max", 5000); | ||||
|     if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; | ||||
|     acq_parameters.doppler_max = doppler_max_; | ||||
|     unsigned int sampled_ms = 1; | ||||
|     //max_dwells_ = configuration_->property(role + ".max_dwells", 1); | ||||
|     //acq_parameters.max_dwells = max_dwells_; | ||||
|     //dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); | ||||
|     //acq_parameters.dump_filename = dump_filename_; | ||||
|     //bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); | ||||
|     //acq_parameters.bit_transition_flag = bit_transition_flag_; | ||||
|     //use_CFAR_ = configuration_->property(role + ".use_CFAR_algorithm", false); | ||||
|     //acq_parameters.use_CFAR_algorithm_flag = use_CFAR_; | ||||
|     //blocking_ = configuration_->property(role + ".blocking", true); | ||||
|     //acq_parameters.blocking = blocking_; | ||||
|     //--- Find number of samples per spreading code (1ms)------------------------- | ||||
|  | ||||
|     acq_pilot_ = configuration_->property(role + ".acquire_pilot", false); | ||||
|     acq_iq_ = configuration_->property(role + ".acquire_iq", false); | ||||
|     if (acq_iq_) | ||||
|         { | ||||
|             acq_pilot_ = false; | ||||
|         } | ||||
|  | ||||
|     unsigned int code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / Galileo_E5a_CODE_CHIP_RATE_HZ * static_cast<double>(Galileo_E5a_CODE_LENGTH_CHIPS))); | ||||
|     acq_parameters.code_length = code_length; | ||||
|     // The FPGA can only use FFT lengths that are a power of two. | ||||
|     float nbits = ceilf(log2f((float)code_length)); | ||||
|     unsigned int nsamples_total = pow(2, nbits); | ||||
|     unsigned int vector_length = nsamples_total; | ||||
|     unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1); | ||||
|     //printf("select_queue_Fpga = %d\n", select_queue_Fpga); | ||||
|     acq_parameters.select_queue_Fpga = select_queue_Fpga; | ||||
|     std::string default_device_name = "/dev/uio0"; | ||||
|     std::string device_name = configuration_->property(role + ".devicename", default_device_name); | ||||
|     acq_parameters.device_name = device_name; | ||||
|     acq_parameters.samples_per_ms = nsamples_total/sampled_ms; | ||||
|     acq_parameters.samples_per_code = nsamples_total; | ||||
|  | ||||
|     //vector_length_ = code_length_ * sampled_ms_; | ||||
|  | ||||
|     // compute all the GALILEO E5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time | ||||
|     // a channel is assigned) | ||||
|     gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(nsamples_total, true);  // Direct FFT | ||||
|     std::complex<float>* code = new std::complex<float>[nsamples_total];  // buffer for the local code | ||||
|     gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||
|     d_all_fft_codes_ = new lv_16sc_t[nsamples_total * Galileo_E5a_NUMBER_OF_CODES];  // memory containing all the possible fft codes for PRN 0 to 32 | ||||
|     float max;                                                        // temporary maxima search | ||||
|  | ||||
|     //printf("creating the E5A acquisition CONT"); | ||||
|     //printf("nsamples_total = %d\n", nsamples_total); | ||||
|  | ||||
|     for (unsigned int PRN = 1; PRN <= Galileo_E5a_NUMBER_OF_CODES; PRN++) | ||||
|         { | ||||
|             //    gr_complex* code = new gr_complex[code_length_]; | ||||
|             char signal_[3]; | ||||
|  | ||||
|             if (acq_iq_) | ||||
|                 { | ||||
|                     strcpy(signal_, "5X"); | ||||
|                 } | ||||
|             else if (acq_pilot_) | ||||
|                 { | ||||
|                     strcpy(signal_, "5Q"); | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     strcpy(signal_, "5I"); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|             galileo_e5_a_code_gen_complex_sampled(code, signal_, PRN, fs_in, 0); | ||||
|  | ||||
|             // fill in zero padding | ||||
|             for (int s = code_length; s < nsamples_total; s++) | ||||
|                 { | ||||
|                     code[s] = std::complex<float>(static_cast<float>(0,0)); | ||||
|                     //code[s] = 0; | ||||
|                 } | ||||
|  | ||||
|             memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total);   // copy to FFT buffer | ||||
|             fft_if->execute();                                                                 // Run the FFT of local code | ||||
|             volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total);  // conjugate values | ||||
|  | ||||
|             max = 0;                                                                           // initialize maximum value | ||||
|             for (unsigned int i = 0; i < nsamples_total; i++)                                  // search for maxima | ||||
|                 { | ||||
|                     if (std::abs(fft_codes_padded[i].real()) > max) | ||||
|                         { | ||||
|                             max = std::abs(fft_codes_padded[i].real()); | ||||
|                         } | ||||
|                     if (std::abs(fft_codes_padded[i].imag()) > max) | ||||
|                         { | ||||
|                             max = std::abs(fft_codes_padded[i].imag()); | ||||
|                         } | ||||
|                 } | ||||
|             for (unsigned int i = 0; i < nsamples_total; i++)  // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs | ||||
|                 { | ||||
|                     d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), | ||||
|                         static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); | ||||
|                 } | ||||
|  | ||||
|         } | ||||
|  | ||||
|  | ||||
|     acq_parameters.all_fft_codes = d_all_fft_codes_; | ||||
|  | ||||
|     // temporary buffers that we can delete | ||||
|     delete[] code; | ||||
|     delete fft_if; | ||||
|     delete[] fft_codes_padded; | ||||
|  | ||||
|     //code_ = new gr_complex[vector_length_]; | ||||
|  | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            item_size_ = sizeof(gr_complex); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            item_size_ = sizeof(lv_16sc_t); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            item_size_ = sizeof(gr_complex); | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
| //        } | ||||
|     //acq_parameters.it_size = item_size_; | ||||
|     //acq_parameters.samples_per_code = code_length_; | ||||
|     //acq_parameters.samples_per_ms = code_length_; | ||||
|     //acq_parameters.sampled_ms = sampled_ms_; | ||||
|     //acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); | ||||
|     //acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); | ||||
|     //acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); | ||||
|     //acquisition_ = pcps_make_acquisition(acq_parameters); | ||||
|     //acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     //DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
|     acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
|     //stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); | ||||
|     channel_ = 0; | ||||
|     //threshold_ = 0.0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = 0; | ||||
|     //printf("creating the E5A acquisition end"); | ||||
| } | ||||
|  | ||||
|  | ||||
| GalileoE5aPcpsAcquisitionFpga::~GalileoE5aPcpsAcquisitionFpga() | ||||
| { | ||||
|     //delete[] code_; | ||||
|     delete[] d_all_fft_codes_; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aPcpsAcquisitionFpga::set_channel(unsigned int channel) | ||||
| { | ||||
|     channel_ = channel; | ||||
|     //acquisition_->set_channel(channel_); | ||||
|     acquisition_fpga_->set_channel(channel_); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aPcpsAcquisitionFpga::set_threshold(float threshold) | ||||
| { | ||||
| //    float pfa = configuration_->property(role_ + boost::lexical_cast<std::string>(channel_) + ".pfa", 0.0); | ||||
| // | ||||
| //    if (pfa == 0.0) | ||||
| //        { | ||||
| //            pfa = configuration_->property(role_ + ".pfa", 0.0); | ||||
| //        } | ||||
| // | ||||
| //    if (pfa == 0.0) | ||||
| //        { | ||||
| //            threshold_ = threshold; | ||||
| //        } | ||||
| // | ||||
| //    else | ||||
| //        { | ||||
| //            threshold_ = calculate_threshold(pfa); | ||||
| //        } | ||||
|  | ||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; | ||||
|  | ||||
|     //acquisition_->set_threshold(threshold_); | ||||
|     acquisition_fpga_->set_threshold(threshold); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) | ||||
| { | ||||
|     doppler_max_ = doppler_max; | ||||
|     //acquisition_->set_doppler_max(doppler_max_); | ||||
|     acquisition_fpga_->set_doppler_max(doppler_max_); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) | ||||
| { | ||||
|     doppler_step_ = doppler_step; | ||||
|     //acquisition_->set_doppler_step(doppler_step_); | ||||
|     acquisition_fpga_->set_doppler_step(doppler_step_); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) | ||||
| { | ||||
|     gnss_synchro_ = gnss_synchro; | ||||
|     //acquisition_->set_gnss_synchro(gnss_synchro_); | ||||
|     acquisition_fpga_->set_gnss_synchro(gnss_synchro_); | ||||
| } | ||||
|  | ||||
|  | ||||
| signed int GalileoE5aPcpsAcquisitionFpga::mag() | ||||
| { | ||||
|     //return acquisition_->mag(); | ||||
|     return acquisition_fpga_->mag(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aPcpsAcquisitionFpga::init() | ||||
| { | ||||
|     //acquisition_->init(); | ||||
|     acquisition_fpga_->init(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aPcpsAcquisitionFpga::set_local_code() | ||||
| { | ||||
| //    gr_complex* code = new gr_complex[code_length_]; | ||||
| //    char signal_[3]; | ||||
| // | ||||
| //    if (acq_iq_) | ||||
| //        { | ||||
| //            strcpy(signal_, "5X"); | ||||
| //        } | ||||
| //    else if (acq_pilot_) | ||||
| //        { | ||||
| //            strcpy(signal_, "5Q"); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            strcpy(signal_, "5I"); | ||||
| //        } | ||||
| // | ||||
| //    galileo_e5_a_code_gen_complex_sampled(code, signal_, gnss_synchro_->PRN, fs_in_, 0); | ||||
| // | ||||
| //    for (unsigned int i = 0; i < sampled_ms_; i++) | ||||
| //        { | ||||
| //            memcpy(code_ + (i * code_length_), code, sizeof(gr_complex) * code_length_); | ||||
| //        } | ||||
|  | ||||
|     //acquisition_->set_local_code(code_); | ||||
|     acquisition_fpga_->set_local_code(); | ||||
| //    delete[] code; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aPcpsAcquisitionFpga::reset() | ||||
| { | ||||
|     //acquisition_->set_active(true); | ||||
|     acquisition_fpga_->set_active(true); | ||||
| } | ||||
|  | ||||
|  | ||||
| //float GalileoE5aPcpsAcquisitionFpga::calculate_threshold(float pfa) | ||||
| //{ | ||||
| //    unsigned int frequency_bins = 0; | ||||
| //    for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_) | ||||
| //        { | ||||
| //            frequency_bins++; | ||||
| //        } | ||||
| //    DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; | ||||
| //    unsigned int ncells = vector_length_ * frequency_bins; | ||||
| //    double exponent = 1 / static_cast<double>(ncells); | ||||
| //    double val = pow(1.0 - pfa, exponent); | ||||
| //    double lambda = double(vector_length_); | ||||
| //    boost::math::exponential_distribution<double> mydist(lambda); | ||||
| //    float threshold = static_cast<float>(quantile(mydist, val)); | ||||
| // | ||||
| //    return threshold; | ||||
| //} | ||||
|  | ||||
|  | ||||
| void GalileoE5aPcpsAcquisitionFpga::set_state(int state) | ||||
| { | ||||
|     //acquisition_->set_state(state); | ||||
|     acquisition_fpga_->set_state(state); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            top_block->connect(stream_to_vector_, 0, acquisition_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            top_block->connect(stream_to_vector_, 0, acquisition_, 0); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
| //        } | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) | ||||
| { | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
| //        } | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_left_block() | ||||
| { | ||||
|     //return stream_to_vector_; | ||||
|     return nullptr; | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_right_block() | ||||
| { | ||||
|     //return acquisition_; | ||||
|     return acquisition_fpga_; | ||||
| } | ||||
| @@ -0,0 +1,175 @@ | ||||
| /*! | ||||
|  * \file galileo_e5a_pcps_acquisition.h | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  Galileo E5a data and pilot Signals | ||||
|  * \author Antonio Ramos, 2018. antonio.ramos(at)cttc.es | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * 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 <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ | ||||
| #define GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ | ||||
|  | ||||
|  | ||||
| #include "acquisition_interface.h" | ||||
| #include "gnss_synchro.h" | ||||
| #include "pcps_acquisition_fpga.h" | ||||
| #include <gnuradio/blocks/stream_to_vector.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr.h> | ||||
| #include <string> | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| class GalileoE5aPcpsAcquisitionFpga : public AcquisitionInterface | ||||
| { | ||||
| public: | ||||
|     GalileoE5aPcpsAcquisitionFpga(ConfigurationInterface* configuration, | ||||
|         std::string role, unsigned int in_streams, | ||||
|         unsigned int out_streams); | ||||
|  | ||||
|     virtual ~GalileoE5aPcpsAcquisitionFpga(); | ||||
|  | ||||
|     inline std::string role() override | ||||
|     { | ||||
|         return role_; | ||||
|     } | ||||
|  | ||||
|     inline std::string implementation() override | ||||
|     { | ||||
|         return "Galileo_E5a_Pcps_Acquisition_Fpga"; | ||||
|     } | ||||
|  | ||||
|     inline size_t item_size() override | ||||
|     { | ||||
|         return item_size_; | ||||
|     } | ||||
|  | ||||
|     void connect(gr::top_block_sptr top_block) override; | ||||
|     void disconnect(gr::top_block_sptr top_block) override; | ||||
|     gr::basic_block_sptr get_left_block() override; | ||||
|     gr::basic_block_sptr get_right_block() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition/tracking common Gnss_Synchro object pointer | ||||
|      * to efficiently exchange synchronization data between acquisition and | ||||
|      *  tracking blocks | ||||
|      */ | ||||
|     void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition channel unique ID | ||||
|      */ | ||||
|     void set_channel(unsigned int channel) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set statistics threshold of PCPS algorithm | ||||
|      */ | ||||
|     void set_threshold(float threshold) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set maximum Doppler off grid search | ||||
|      */ | ||||
|     void set_doppler_max(unsigned int doppler_max) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set Doppler steps for the grid search | ||||
|      */ | ||||
|     void set_doppler_step(unsigned int doppler_step) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Initializes acquisition algorithm. | ||||
|      */ | ||||
|     void init() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Sets local Galileo E5a code for PCPS acquisition algorithm. | ||||
|      */ | ||||
|     void set_local_code() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns the maximum peak of grid search | ||||
|      */ | ||||
|     signed int mag() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Restart acquisition algorithm | ||||
|      */ | ||||
|     void reset() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief If 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) override; | ||||
|  | ||||
| private: | ||||
|     //float calculate_threshold(float pfa); | ||||
|  | ||||
|     ConfigurationInterface* configuration_; | ||||
|  | ||||
|     pcps_acquisition_fpga_sptr acquisition_fpga_; | ||||
|     gr::blocks::stream_to_vector::sptr stream_to_vector_; | ||||
|  | ||||
|     size_t item_size_; | ||||
|  | ||||
|     std::string item_type_; | ||||
|     std::string dump_filename_; | ||||
|     std::string role_; | ||||
|  | ||||
|     bool bit_transition_flag_; | ||||
|     bool dump_; | ||||
|     bool acq_pilot_; | ||||
|     bool use_CFAR_; | ||||
|     bool blocking_; | ||||
|     bool acq_iq_; | ||||
|  | ||||
|     unsigned int vector_length_; | ||||
|     unsigned int code_length_; | ||||
|     unsigned int channel_; | ||||
|     unsigned int doppler_max_; | ||||
|     unsigned int doppler_step_; | ||||
|     unsigned int sampled_ms_; | ||||
|     unsigned int max_dwells_; | ||||
|     unsigned int in_streams_; | ||||
|     unsigned int out_streams_; | ||||
|  | ||||
|     long fs_in_; | ||||
|  | ||||
|  | ||||
|     float threshold_; | ||||
|  | ||||
|     /* | ||||
|     std::complex<float>* codeI_; | ||||
|     std::complex<float>* codeQ_; | ||||
|     */ | ||||
|  | ||||
|     gr_complex* code_; | ||||
|  | ||||
|     Gnss_Synchro* gnss_synchro_; | ||||
|  | ||||
|     // extra for the FPGA | ||||
|     lv_16sc_t* d_all_fft_codes_;  // memory that contains all the code ffts | ||||
| }; | ||||
| #endif /* GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ */ | ||||
| @@ -11,7 +11,7 @@ | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (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 | ||||
| @@ -29,20 +29,21 @@ | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "gps_l1_ca_pcps_acquisition_fpga.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "gnss_sdr_flags.h" | ||||
| #include "GPS_L1_CA.h" | ||||
| #include "gps_l1_ca_pcps_acquisition_fpga.h" | ||||
| #include "gps_sdr_signal_processing.h" | ||||
| #include "GPS_L1_CA.h" | ||||
| #include <gnuradio/fft/fft.h> | ||||
| #include <glog/logging.h> | ||||
| #include <new> | ||||
|  | ||||
|  | ||||
| #define NUM_PRNs 32 | ||||
|  | ||||
| using google::LogMessage; | ||||
| @@ -59,6 +60,8 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( | ||||
|  | ||||
|     long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||
|     long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|     //fs_in = fs_in/2.0; // downampling filter | ||||
|     //printf("####### DEBUG Acq: fs_in = %d\n", fs_in); | ||||
|     acq_parameters.fs_in = fs_in; | ||||
|     acq_parameters.samples_per_code = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in))); | ||||
|     doppler_max_ = configuration_->property(role + ".doppler_max", 5000); | ||||
| @@ -67,41 +70,54 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( | ||||
|     unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1); | ||||
|     acq_parameters.sampled_ms = sampled_ms; | ||||
|     unsigned int code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); | ||||
|  | ||||
|     acq_parameters.code_length = code_length; | ||||
|     // The FPGA can only use FFT lengths that are a power of two. | ||||
|     float nbits = ceilf(log2f((float)code_length)); | ||||
|     unsigned int nsamples_total = pow(2, nbits); | ||||
|     unsigned int vector_length = nsamples_total * sampled_ms; | ||||
|     unsigned int vector_length = nsamples_total; | ||||
|     unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0); | ||||
|     acq_parameters.select_queue_Fpga = select_queue_Fpga; | ||||
|     std::string default_device_name = "/dev/uio0"; | ||||
|     std::string device_name = configuration_->property(role + ".devicename", default_device_name); | ||||
|     acq_parameters.device_name = device_name; | ||||
|     acq_parameters.samples_per_ms = nsamples_total; | ||||
|     acq_parameters.samples_per_ms = nsamples_total / sampled_ms; | ||||
|     acq_parameters.samples_per_code = nsamples_total; | ||||
|  | ||||
|     // compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time | ||||
|     // a channel is assigned) | ||||
|  | ||||
|     gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true);  // Direct FFT | ||||
|     // allocate memory to compute all the PRNs and compute all the possible codes | ||||
|     std::complex<float>* code = new std::complex<float>[nsamples_total];  // buffer for the local code | ||||
|     gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||
|     d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs];  // memory containing all the possible fft codes for PRN 0 to 32 | ||||
|     float max;                                                    // temporary maxima search | ||||
|  | ||||
|     for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) | ||||
|         { | ||||
|             gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0);  // generate PRN code | ||||
|             // fill in zero padding | ||||
|             for (unsigned int s = code_length; s < nsamples_total; s++) | ||||
|             for (int s = code_length; s < nsamples_total; s++) | ||||
|                 { | ||||
|                     code[s] = 0; | ||||
|                     code[s] = std::complex<float>(static_cast<float>(0, 0)); | ||||
|                     //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 | ||||
|  | ||||
|  | ||||
|             //            // debug | ||||
|             //            char filename[25]; | ||||
|             //            FILE *fid; | ||||
|             //            sprintf(filename,"fft_gps_prn%d.txt", PRN); | ||||
|             //            fid = fopen(filename, "w"); | ||||
|             //            for (unsigned int kk=0;kk< nsamples_total; kk++) | ||||
|             //                { | ||||
|             //                    fprintf(fid, "%f\n", fft_codes_padded[kk].real()); | ||||
|             //                    fprintf(fid, "%f\n", fft_codes_padded[kk].imag()); | ||||
|             //                } | ||||
|             //            fclose(fid); | ||||
|  | ||||
|             max = 0;                                           // initialize maximum value | ||||
|             for (unsigned int i = 0; i < nsamples_total; i++)  // search for maxima | ||||
|                 { | ||||
| @@ -116,12 +132,31 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( | ||||
|                 } | ||||
|             for (unsigned int i = 0; i < nsamples_total; i++)  // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs | ||||
|                 { | ||||
|                     d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), | ||||
|                         static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); | ||||
|                 } | ||||
|                     //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), | ||||
|                     //    static_cast<int>(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); | ||||
|                     //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(16*floor(fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)), | ||||
|                     //    static_cast<int>(16*floor(fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max))); | ||||
|                     //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), | ||||
|                     //    static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); | ||||
|                     d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), | ||||
|                         static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); | ||||
|                 } | ||||
|  | ||||
|     // acq_parameters | ||||
|  | ||||
|             ////            // debug | ||||
|             //            char filename2[25]; | ||||
|             //            FILE *fid2; | ||||
|             //            sprintf(filename2,"fft_gps_prn%d_norm_new.txt", PRN); | ||||
|             //            fid2 = fopen(filename2, "w"); | ||||
|             //            for (unsigned int kk=0;kk< nsamples_total; kk++) | ||||
|             //                { | ||||
|             //                    fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real()); | ||||
|             //                    fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag()); | ||||
|             //                } | ||||
|             //            fclose(fid2); | ||||
|         } | ||||
|  | ||||
|     //acq_parameters | ||||
|     acq_parameters.all_fft_codes = d_all_fft_codes_; | ||||
|  | ||||
|     // temporary buffers that we can delete | ||||
| @@ -135,14 +170,6 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( | ||||
|     channel_ = 0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = 0; | ||||
|     if (in_streams_ > 1) | ||||
|         { | ||||
|             LOG(ERROR) << "This implementation only supports one input stream"; | ||||
|         } | ||||
|     if (out_streams_ > 0) | ||||
|         { | ||||
|             LOG(ERROR) << "This implementation does not provide an output stream"; | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -161,6 +188,8 @@ void GpsL1CaPcpsAcquisitionFpga::set_channel(unsigned int channel) | ||||
|  | ||||
| void GpsL1CaPcpsAcquisitionFpga::set_threshold(float threshold) | ||||
| { | ||||
|     // the .pfa parameter and the threshold calculation is only used for the CFAR algorithm. | ||||
|     // We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such. | ||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; | ||||
|     acquisition_fpga_->set_threshold(threshold); | ||||
| } | ||||
| @@ -216,26 +245,21 @@ void GpsL1CaPcpsAcquisitionFpga::set_state(int state) | ||||
|     acquisition_fpga_->set_state(state); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL1CaPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     if (top_block) | ||||
|         {  // nothing to disconnect | ||||
|         } | ||||
|     // nothing to connect | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL1CaPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     if (top_block) | ||||
|         {  // nothing to disconnect | ||||
|         } | ||||
|     // nothing to disconnect | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GpsL1CaPcpsAcquisitionFpga::get_left_block() | ||||
| { | ||||
|     return acquisition_fpga_; | ||||
|     return nullptr; | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -68,7 +68,7 @@ public: | ||||
|      */ | ||||
|     inline std::string implementation() override | ||||
|     { | ||||
|         return "GPS_L1_CA_PCPS_Acquisition"; | ||||
|         return "GPS_L1_CA_PCPS_Acquisition_Fpga"; | ||||
|     } | ||||
|  | ||||
|     inline size_t item_size() override | ||||
|   | ||||
| @@ -0,0 +1,398 @@ | ||||
| /*! | ||||
|  * \file gps_l2_m_pcps_acquisition.cc | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  GPS L2 M signals | ||||
|  * \authors <ul> | ||||
|  *          <li> Javier Arribas, 2015. jarribas(at)cttc.es | ||||
|  *          </ul> | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "gps_l2_m_pcps_acquisition_fpga.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "gps_l2c_signal.h" | ||||
| #include "GPS_L2C.h" | ||||
| #include "gnss_sdr_flags.h" | ||||
| #include <boost/math/distributions/exponential.hpp> | ||||
| #include <glog/logging.h> | ||||
|  | ||||
| #define NUM_PRNs 32 | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( | ||||
|     ConfigurationInterface* configuration, std::string role, | ||||
|     unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) | ||||
| { | ||||
|     //pcpsconf_t acq_parameters; | ||||
|     pcpsconf_fpga_t acq_parameters; | ||||
|     configuration_ = configuration; | ||||
|     std::string default_item_type = "gr_complex"; | ||||
|     std::string default_dump_filename = "./data/acquisition.dat"; | ||||
|  | ||||
|     LOG(INFO) << "role " << role; | ||||
|  | ||||
|     item_type_ = configuration_->property(role + ".item_type", default_item_type); | ||||
|     //float pfa =  configuration_->property(role + ".pfa", 0.0); | ||||
|  | ||||
|     long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|     acq_parameters.fs_in = fs_in_; | ||||
|     //if_ = configuration_->property(role + ".if", 0); | ||||
|     //acq_parameters.freq = if_; | ||||
|     //dump_ = configuration_->property(role + ".dump", false); | ||||
|     //acq_parameters.dump = dump_; | ||||
|     //blocking_ = configuration_->property(role + ".blocking", true); | ||||
|     //acq_parameters.blocking = blocking_; | ||||
|     doppler_max_ = configuration->property(role + ".doppler_max", 5000); | ||||
|     if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; | ||||
|     acq_parameters.doppler_max = doppler_max_; | ||||
|     //bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); | ||||
|     //acq_parameters.bit_transition_flag = bit_transition_flag_; | ||||
|     //use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true);  //will be false in future versions | ||||
|     //acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; | ||||
|     //max_dwells_ = configuration_->property(role + ".max_dwells", 1); | ||||
|     //acq_parameters.max_dwells = max_dwells_; | ||||
|     //dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); | ||||
|     //acq_parameters.dump_filename = dump_filename_; | ||||
|     //--- Find number of samples per spreading code ------------------------- | ||||
|     //code_length_ = std::round(static_cast<double>(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast<double>(GPS_L2_M_CODE_LENGTH_CHIPS))); | ||||
|  | ||||
|     acq_parameters.sampled_ms = 20; | ||||
|     unsigned code_length = std::round(static_cast<double>(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast<double>(GPS_L2_M_CODE_LENGTH_CHIPS))); | ||||
|     acq_parameters.code_length = code_length; | ||||
|     // The FPGA can only use FFT lengths that are a power of two. | ||||
|     float nbits = ceilf(log2f((float)code_length)); | ||||
|     unsigned int nsamples_total = pow(2, nbits); | ||||
|     unsigned int vector_length = nsamples_total; | ||||
|     unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0); | ||||
|     acq_parameters.select_queue_Fpga = select_queue_Fpga; | ||||
|     std::string default_device_name = "/dev/uio0"; | ||||
|     std::string device_name = configuration_->property(role + ".devicename", default_device_name); | ||||
|     acq_parameters.device_name = device_name; | ||||
|     acq_parameters.samples_per_ms = nsamples_total/acq_parameters.sampled_ms; | ||||
|     //acq_parameters.samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001)); | ||||
|     acq_parameters.samples_per_code = nsamples_total; | ||||
|  | ||||
|     // compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time | ||||
|     // a channel is assigned) | ||||
|     gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true);  // Direct FFT | ||||
|     // allocate memory to compute all the PRNs and compute all the possible codes | ||||
|     std::complex<float>* code = new std::complex<float>[nsamples_total];  // buffer for the local code | ||||
|     gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||
|     d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs];  // memory containing all the possible fft codes for PRN 0 to 32 | ||||
|     float max;                                                    // temporary maxima search | ||||
|     for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) | ||||
|         { | ||||
|             gps_l2c_m_code_gen_complex_sampled(code, PRN, fs_in_); | ||||
|             // fill in zero padding | ||||
|             for (int s = code_length; s < nsamples_total; s++) | ||||
|                 { | ||||
|                     code[s] = std::complex<float>(static_cast<float>(0,0)); | ||||
|                     //code[s] = 0; | ||||
|                 } | ||||
|             memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total);   // copy to FFT buffer | ||||
|             fft_if->execute();                                                                 // Run the FFT of local code | ||||
|             volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total);  // conjugate values | ||||
|             max = 0;                                                                           // initialize maximum value | ||||
|             for (unsigned int i = 0; i < nsamples_total; i++)                                  // search for maxima | ||||
|                 { | ||||
|                     if (std::abs(fft_codes_padded[i].real()) > max) | ||||
|                         { | ||||
|                             max = std::abs(fft_codes_padded[i].real()); | ||||
|                         } | ||||
|                     if (std::abs(fft_codes_padded[i].imag()) > max) | ||||
|                         { | ||||
|                             max = std::abs(fft_codes_padded[i].imag()); | ||||
|                         } | ||||
|                 } | ||||
|             for (unsigned int i = 0; i < nsamples_total; i++)  // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs | ||||
|                 { | ||||
|                     d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), | ||||
|                         static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); | ||||
|                 } | ||||
|  | ||||
|         } | ||||
|  | ||||
|     //acq_parameters | ||||
|     acq_parameters.all_fft_codes = d_all_fft_codes_; | ||||
|  | ||||
|     // temporary buffers that we can delete | ||||
|     delete[] code; | ||||
|     delete fft_if; | ||||
|     delete[] fft_codes_padded; | ||||
|  | ||||
|     acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
|     channel_ = 0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = 0; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //    vector_length_ = code_length_; | ||||
| // | ||||
| //    if (bit_transition_flag_) | ||||
| //        { | ||||
| //            vector_length_ *= 2; | ||||
| //        } | ||||
|  | ||||
| //    code_ = new gr_complex[vector_length_]; | ||||
| // | ||||
| //    if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            item_size_ = sizeof(lv_16sc_t); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            item_size_ = sizeof(gr_complex); | ||||
| //        } | ||||
|     //acq_parameters.samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001)); | ||||
|     //acq_parameters.samples_per_code = code_length_; | ||||
|     //acq_parameters.it_size = item_size_; | ||||
|     //acq_parameters.sampled_ms = 20; | ||||
|     //acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); | ||||
|     //acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); | ||||
|     //acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", true); | ||||
|     //acquisition_ = pcps_make_acquisition(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
| //    stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); | ||||
| //    DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; | ||||
| // | ||||
| //    if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); | ||||
| //            float_to_complex_ = gr::blocks::float_to_complex::make(); | ||||
| //        } | ||||
|  | ||||
| //    channel_ = 0; | ||||
|     threshold_ = 0.0; | ||||
| //    doppler_step_ = 0; | ||||
| //    gnss_synchro_ = 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| GpsL2MPcpsAcquisitionFpga::~GpsL2MPcpsAcquisitionFpga() | ||||
| { | ||||
|     //delete[] code_; | ||||
|     delete[] d_all_fft_codes_; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL2MPcpsAcquisitionFpga::set_channel(unsigned int channel) | ||||
| { | ||||
|     channel_ = channel; | ||||
|     acquisition_fpga_->set_channel(channel_); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL2MPcpsAcquisitionFpga::set_threshold(float threshold) | ||||
| { | ||||
| //    float pfa = configuration_->property(role_ + boost::lexical_cast<std::string>(channel_) + ".pfa", 0.0); | ||||
| // | ||||
| //    if (pfa == 0.0) | ||||
| //        { | ||||
| //            pfa = configuration_->property(role_ + ".pfa", 0.0); | ||||
| //        } | ||||
| //    if (pfa == 0.0) | ||||
| //        { | ||||
| //            threshold_ = threshold; | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            threshold_ = calculate_threshold(pfa); | ||||
| //        } | ||||
|  | ||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; | ||||
|  | ||||
|     acquisition_fpga_->set_threshold(threshold_); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL2MPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) | ||||
| { | ||||
|     doppler_max_ = doppler_max; | ||||
|  | ||||
|     acquisition_fpga_->set_doppler_max(doppler_max_); | ||||
| } | ||||
|  | ||||
|  | ||||
| // Be aware that Doppler step should be set to 2/(3T) Hz, where T is the coherent integration time (GPS L2 period is 0.02s) | ||||
| // Doppler bin minimum size= 33 Hz | ||||
| void GpsL2MPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) | ||||
| { | ||||
|     doppler_step_ = doppler_step; | ||||
|  | ||||
|     acquisition_fpga_->set_doppler_step(doppler_step_); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL2MPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) | ||||
| { | ||||
|     gnss_synchro_ = gnss_synchro; | ||||
|  | ||||
|     acquisition_fpga_->set_gnss_synchro(gnss_synchro_); | ||||
| } | ||||
|  | ||||
|  | ||||
| signed int GpsL2MPcpsAcquisitionFpga::mag() | ||||
| { | ||||
|     return acquisition_fpga_->mag(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL2MPcpsAcquisitionFpga::init() | ||||
| { | ||||
|     acquisition_fpga_->init(); | ||||
|     //set_local_code(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL2MPcpsAcquisitionFpga::set_local_code() | ||||
| { | ||||
|     //gps_l2c_m_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_); | ||||
|  | ||||
|     //acquisition_fpga_->set_local_code(code_); | ||||
|     acquisition_fpga_->set_local_code(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL2MPcpsAcquisitionFpga::reset() | ||||
| { | ||||
|     acquisition_fpga_->set_active(true); | ||||
| } | ||||
|  | ||||
| void GpsL2MPcpsAcquisitionFpga::set_state(int state) | ||||
| { | ||||
|     acquisition_fpga_->set_state(state); | ||||
| } | ||||
|  | ||||
|  | ||||
| //float GpsL2MPcpsAcquisitionFpga::calculate_threshold(float pfa) | ||||
| //{ | ||||
| //    //Calculate the threshold | ||||
| //    unsigned int frequency_bins = 0; | ||||
| //    for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_) | ||||
| //        { | ||||
| //            frequency_bins++; | ||||
| //        } | ||||
| //    DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; | ||||
| //    unsigned int ncells = vector_length_ * frequency_bins; | ||||
| //    double exponent = 1.0 / static_cast<double>(ncells); | ||||
| //    double val = pow(1.0 - pfa, exponent); | ||||
| //    double lambda = double(vector_length_); | ||||
| //    boost::math::exponential_distribution<double> mydist(lambda); | ||||
| //    float threshold = static_cast<float>(quantile(mydist, val)); | ||||
| // | ||||
| //    return threshold; | ||||
| //} | ||||
|  | ||||
|  | ||||
| void GpsL2MPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            top_block->connect(stream_to_vector_, 0, acquisition_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            top_block->connect(stream_to_vector_, 0, acquisition_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); | ||||
| //            top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); | ||||
| //            top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); | ||||
| //            top_block->connect(stream_to_vector_, 0, acquisition_, 0); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
| //        } | ||||
|  | ||||
|     // nothing to connect | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL2MPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) | ||||
| { | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            // Since a byte-based acq implementation is not available, | ||||
| //            // we just convert cshorts to gr_complex | ||||
| //            top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); | ||||
| //            top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); | ||||
| //            top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); | ||||
| //            top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
| //        } | ||||
|  | ||||
|     // nothing to disconnect | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GpsL2MPcpsAcquisitionFpga::get_left_block() | ||||
| { | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            return stream_to_vector_; | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            return stream_to_vector_; | ||||
| //        } | ||||
| //    else if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            return cbyte_to_float_x2_; | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
| //            return nullptr; | ||||
| //        } | ||||
|     return nullptr; | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GpsL2MPcpsAcquisitionFpga::get_right_block() | ||||
| { | ||||
|     return acquisition_fpga_; | ||||
| } | ||||
| @@ -0,0 +1,171 @@ | ||||
| /*! | ||||
|  * \file gps_l2_m_pcps_acquisition.h | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  GPS L2 M signals | ||||
|  * \authors <ul> | ||||
|  *          <li> Javier Arribas, 2015. jarribas(at)cttc.es | ||||
|  *          </ul> | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H_ | ||||
| #define GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H_ | ||||
|  | ||||
| #include "acquisition_interface.h" | ||||
| #include "gnss_synchro.h" | ||||
| #include "pcps_acquisition_fpga.h" | ||||
| #include "complex_byte_to_float_x2.h" | ||||
| #include <gnuradio/blocks/stream_to_vector.h> | ||||
| #include <gnuradio/blocks/float_to_complex.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr.h> | ||||
| #include <string> | ||||
|  | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| /*! | ||||
|  * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface | ||||
|  *  for GPS L2 M signals | ||||
|  */ | ||||
| class GpsL2MPcpsAcquisitionFpga : public AcquisitionInterface | ||||
| { | ||||
| public: | ||||
|     GpsL2MPcpsAcquisitionFpga(ConfigurationInterface* configuration, | ||||
|         std::string role, unsigned int in_streams, | ||||
|         unsigned int out_streams); | ||||
|  | ||||
|     virtual ~GpsL2MPcpsAcquisitionFpga(); | ||||
|  | ||||
|     inline std::string role() override | ||||
|     { | ||||
|         return role_; | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns "GPS_L2_M_PCPS_Acquisition" | ||||
|      */ | ||||
|     inline std::string implementation() override | ||||
|     { | ||||
|         return "GPS_L2_M_PCPS_Acquisition"; | ||||
|     } | ||||
|  | ||||
|     inline size_t item_size() override | ||||
|     { | ||||
|         return item_size_; | ||||
|     } | ||||
|  | ||||
|     void connect(gr::top_block_sptr top_block) override; | ||||
|     void disconnect(gr::top_block_sptr top_block) override; | ||||
|     gr::basic_block_sptr get_left_block() override; | ||||
|     gr::basic_block_sptr get_right_block() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition/tracking common Gnss_Synchro object pointer | ||||
|      * to efficiently exchange synchronization data between acquisition and | ||||
|      *  tracking blocks | ||||
|      */ | ||||
|     void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition channel unique ID | ||||
|      */ | ||||
|     void set_channel(unsigned int channel) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set statistics threshold of PCPS algorithm | ||||
|      */ | ||||
|     void set_threshold(float threshold) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set maximum Doppler off grid search | ||||
|      */ | ||||
|     void set_doppler_max(unsigned int doppler_max) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set Doppler steps for the grid search | ||||
|      */ | ||||
|     void set_doppler_step(unsigned int doppler_step) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Initializes acquisition algorithm. | ||||
|      */ | ||||
|     void init() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Sets local code for GPS L2/M PCPS acquisition algorithm. | ||||
|      */ | ||||
|     void set_local_code() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns the maximum peak of grid search | ||||
|      */ | ||||
|     signed int mag() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Restart acquisition algorithm | ||||
|      */ | ||||
|     void reset() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief If state = 1, it forces the block to start acquiring from the first sample | ||||
|      */ | ||||
|     void set_state(int state) override; | ||||
|  | ||||
| private: | ||||
|     ConfigurationInterface* configuration_; | ||||
|     //pcps_acquisition_sptr acquisition_; | ||||
|     pcps_acquisition_fpga_sptr acquisition_fpga_; | ||||
|     gr::blocks::stream_to_vector::sptr stream_to_vector_; | ||||
|     gr::blocks::float_to_complex::sptr float_to_complex_; | ||||
|     complex_byte_to_float_x2_sptr cbyte_to_float_x2_; | ||||
|     size_t item_size_; | ||||
|     std::string item_type_; | ||||
|     unsigned int vector_length_; | ||||
|     unsigned int code_length_; | ||||
|     bool bit_transition_flag_; | ||||
|     bool use_CFAR_algorithm_flag_; | ||||
|     unsigned int channel_; | ||||
|     float threshold_; | ||||
|     unsigned int doppler_max_; | ||||
|     unsigned int doppler_step_; | ||||
|     unsigned int max_dwells_; | ||||
|     long fs_in_; | ||||
|     //long if_; | ||||
|     bool dump_; | ||||
|     bool blocking_; | ||||
|     std::string dump_filename_; | ||||
|     std::complex<float>* code_; | ||||
|     Gnss_Synchro* gnss_synchro_; | ||||
|     std::string role_; | ||||
|     unsigned int in_streams_; | ||||
|     unsigned int out_streams_; | ||||
|  | ||||
|     lv_16sc_t* d_all_fft_codes_;  // memory that contains all the code ffts | ||||
|  | ||||
|     //float calculate_threshold(float pfa); | ||||
| }; | ||||
|  | ||||
| #endif /* GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H_ */ | ||||
| @@ -0,0 +1,404 @@ | ||||
| /*! | ||||
|  * \file gps_l5i pcps_acquisition.cc | ||||
|  * \brief Adapts a PCPS acquisition block to an Acquisition Interface for | ||||
|  *  GPS L5i signals | ||||
|  * \authors <ul> | ||||
|  *          <li> Javier Arribas, 2017. jarribas(at)cttc.es | ||||
|  *          </ul> | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * 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 <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "gps_l5i_pcps_acquisition_fpga.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "gps_l5_signal.h" | ||||
| #include "GPS_L5.h" | ||||
| #include "gnss_sdr_flags.h" | ||||
| #include <boost/math/distributions/exponential.hpp> | ||||
| #include <glog/logging.h> | ||||
|  | ||||
| #define NUM_PRNs 32 | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( | ||||
|     ConfigurationInterface* configuration, std::string role, | ||||
|     unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) | ||||
| { | ||||
| 	//printf("L5 ACQ CLASS CREATED\n"); | ||||
| 	pcpsconf_fpga_t acq_parameters; | ||||
|     configuration_ = configuration; | ||||
|     std::string default_item_type = "gr_complex"; | ||||
|     std::string default_dump_filename = "./data/acquisition.dat"; | ||||
|  | ||||
|     LOG(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); | ||||
|     long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|     acq_parameters.fs_in = fs_in; | ||||
|     //if_ = configuration_->property(role + ".if", 0); | ||||
|     //acq_parameters.freq = if_; | ||||
|     //dump_ = configuration_->property(role + ".dump", false); | ||||
|     //acq_parameters.dump = dump_; | ||||
|     //blocking_ = configuration_->property(role + ".blocking", true); | ||||
|     //acq_parameters.blocking = blocking_; | ||||
|     doppler_max_ = configuration->property(role + ".doppler_max", 5000); | ||||
|     if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; | ||||
|     acq_parameters.doppler_max = doppler_max_; | ||||
|     //acq_parameters.sampled_ms = 1; | ||||
|     unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1); | ||||
|     acq_parameters.sampled_ms = sampled_ms; | ||||
|  | ||||
|     //printf("L5 ACQ CLASS MID 0\n"); | ||||
|  | ||||
|     //bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); | ||||
|     //acq_parameters.bit_transition_flag = bit_transition_flag_; | ||||
|     //use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true);  //will be false in future versions | ||||
|     //acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; | ||||
|     //max_dwells_ = configuration_->property(role + ".max_dwells", 1); | ||||
|     //acq_parameters.max_dwells = max_dwells_; | ||||
|     //dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); | ||||
|     //acq_parameters.dump_filename = dump_filename_; | ||||
|     //--- Find number of samples per spreading code ------------------------- | ||||
|     unsigned int code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (GPS_L5i_CODE_RATE_HZ / static_cast<double>(GPS_L5i_CODE_LENGTH_CHIPS)))); | ||||
|     acq_parameters.code_length = code_length; | ||||
|     // The FPGA can only use FFT lengths that are a power of two. | ||||
|     float nbits = ceilf(log2f((float)code_length)); | ||||
|     unsigned int nsamples_total = pow(2, nbits); | ||||
|     unsigned int vector_length = nsamples_total; | ||||
|     unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1); | ||||
|     acq_parameters.select_queue_Fpga = select_queue_Fpga; | ||||
|     std::string default_device_name = "/dev/uio0"; | ||||
|     std::string device_name = configuration_->property(role + ".devicename", default_device_name); | ||||
|     acq_parameters.device_name = device_name; | ||||
|     acq_parameters.samples_per_ms = nsamples_total; | ||||
|     acq_parameters.samples_per_code = nsamples_total; | ||||
|     //printf("L5 ACQ CLASS MID 01\n"); | ||||
|     // compute all the GPS L5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time | ||||
|     // a channel is assigned) | ||||
|     gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true);  // Direct FFT | ||||
|     //printf("L5 ACQ CLASS MID 02\n"); | ||||
|     std::complex<float>* code = new gr_complex[vector_length]; | ||||
|     //printf("L5 ACQ CLASS MID 03\n"); | ||||
|     gr_complex* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||
|     //printf("L5 ACQ CLASS MID 04\n"); | ||||
|     d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs];  // memory containing all the possible fft codes for PRN 0 to 32 | ||||
|  | ||||
|     //printf("L5 ACQ CLASS MID 1 vector_length = %d\n", vector_length); | ||||
|  | ||||
|     float max;                                                    // temporary maxima search | ||||
|     for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) | ||||
|     { | ||||
|     	//printf("L5 ACQ CLASS processing PRN = %d\n", PRN); | ||||
|     	gps_l5i_code_gen_complex_sampled(code, PRN, fs_in); | ||||
|     	//printf("L5 ACQ CLASS processing PRN = %d (cont) \n", PRN); | ||||
|     	// fill in zero padding | ||||
|         for (int s = code_length; s < nsamples_total; s++) | ||||
|             { | ||||
|                 code[s] = std::complex<float>(static_cast<float>(0,0)); | ||||
|                 //code[s] = 0; | ||||
|             } | ||||
| 		memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total);   // copy to FFT buffer | ||||
| 		fft_if->execute();                                                                 // Run the FFT of local code | ||||
| 		volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total);  // conjugate values | ||||
|  | ||||
|         max = 0;                                                                           // initialize maximum value | ||||
|         for (unsigned int i = 0; i < nsamples_total; i++)                                  // search for maxima | ||||
|             { | ||||
|                 if (std::abs(fft_codes_padded[i].real()) > max) | ||||
|                     { | ||||
|                         max = std::abs(fft_codes_padded[i].real()); | ||||
|                     } | ||||
|                 if (std::abs(fft_codes_padded[i].imag()) > max) | ||||
|                     { | ||||
|                         max = std::abs(fft_codes_padded[i].imag()); | ||||
|                     } | ||||
|             } | ||||
|         for (unsigned int i = 0; i < nsamples_total; i++)  // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs | ||||
|             { | ||||
|                 //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), | ||||
|                 //    static_cast<int>(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); | ||||
|                 //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(16*floor(fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)), | ||||
|                 //    static_cast<int>(16*floor(fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max))); | ||||
|                 //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), | ||||
|                 //    static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); | ||||
|                 d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), | ||||
|                     static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); | ||||
|             } | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     //printf("L5 ACQ CLASS MID 2\n"); | ||||
|  | ||||
|     //acq_parameters | ||||
|     acq_parameters.all_fft_codes = d_all_fft_codes_; | ||||
|  | ||||
|     // temporary buffers that we can delete | ||||
|     delete[] code; | ||||
|     delete fft_if; | ||||
|     delete[] fft_codes_padded; | ||||
| //    vector_length_ = code_length_; | ||||
| // | ||||
| //    if (bit_transition_flag_) | ||||
| //        { | ||||
| //            vector_length_ *= 2; | ||||
| //        } | ||||
| // | ||||
| //    code_ = new gr_complex[vector_length_]; | ||||
| // | ||||
| //    if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            item_size_ = sizeof(lv_16sc_t); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            item_size_ = sizeof(gr_complex); | ||||
| //        } | ||||
| //    acq_parameters.samples_per_code = code_length_; | ||||
| //    acq_parameters.samples_per_ms = code_length_; | ||||
| //    acq_parameters.it_size = item_size_; | ||||
|     //acq_parameters.sampled_ms = 1; | ||||
| //    acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); | ||||
| //    acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); | ||||
| //    acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); | ||||
| //    acquisition_fpga_ = pcps_make_acquisition(acq_parameters); | ||||
| //    DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
|     acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
| //    stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); | ||||
| //    DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; | ||||
| // | ||||
| //    if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); | ||||
| //            float_to_complex_ = gr::blocks::float_to_complex::make(); | ||||
| //        } | ||||
|  | ||||
|     channel_ = 0; | ||||
| //    threshold_ = 0.0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = 0; | ||||
|     //printf("L5 ACQ CLASS FINISHED\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| GpsL5iPcpsAcquisitionFpga::~GpsL5iPcpsAcquisitionFpga() | ||||
| { | ||||
|     //delete[] code_; | ||||
|     delete[] d_all_fft_codes_; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL5iPcpsAcquisitionFpga::set_channel(unsigned int channel) | ||||
| { | ||||
|     channel_ = channel; | ||||
|     acquisition_fpga_->set_channel(channel_); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL5iPcpsAcquisitionFpga::set_threshold(float threshold) | ||||
| { | ||||
| //    float pfa = configuration_->property(role_ + boost::lexical_cast<std::string>(channel_) + ".pfa", 0.0); | ||||
| // | ||||
| //    if (pfa == 0.0) | ||||
| //        { | ||||
| //            pfa = configuration_->property(role_ + ".pfa", 0.0); | ||||
| //        } | ||||
| //    if (pfa == 0.0) | ||||
| //        { | ||||
| //            threshold_ = threshold; | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            threshold_ = calculate_threshold(pfa); | ||||
| //        } | ||||
|  | ||||
| //    DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; | ||||
|  | ||||
|     // the .pfa parameter and the threshold calculation is only used for the CFAR algorithm. | ||||
|     // We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such. | ||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; | ||||
|     acquisition_fpga_->set_threshold(threshold); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL5iPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) | ||||
| { | ||||
|     doppler_max_ = doppler_max; | ||||
|     acquisition_fpga_->set_doppler_max(doppler_max_); | ||||
| } | ||||
|  | ||||
|  | ||||
| // Be aware that Doppler step should be set to 2/(3T) Hz, where T is the coherent integration time (GPS L2 period is 0.02s) | ||||
| // Doppler bin minimum size= 33 Hz | ||||
| void GpsL5iPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) | ||||
| { | ||||
|     doppler_step_ = doppler_step; | ||||
|     acquisition_fpga_->set_doppler_step(doppler_step_); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL5iPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) | ||||
| { | ||||
|     gnss_synchro_ = gnss_synchro; | ||||
|     acquisition_fpga_->set_gnss_synchro(gnss_synchro_); | ||||
| } | ||||
|  | ||||
|  | ||||
| signed int GpsL5iPcpsAcquisitionFpga::mag() | ||||
| { | ||||
| 	return acquisition_fpga_->mag(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL5iPcpsAcquisitionFpga::init() | ||||
| { | ||||
| 	acquisition_fpga_->init(); | ||||
| } | ||||
|  | ||||
| void GpsL5iPcpsAcquisitionFpga::set_local_code() | ||||
| { | ||||
| 	acquisition_fpga_->set_local_code(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL5iPcpsAcquisitionFpga::reset() | ||||
| { | ||||
|     acquisition_fpga_->set_active(true); | ||||
| } | ||||
|  | ||||
| void GpsL5iPcpsAcquisitionFpga::set_state(int state) | ||||
| { | ||||
|     acquisition_fpga_->set_state(state); | ||||
| } | ||||
|  | ||||
|  | ||||
| //float GpsL5iPcpsAcquisitionFpga::calculate_threshold(float pfa) | ||||
| //{ | ||||
| //    //Calculate the threshold | ||||
| //    unsigned int frequency_bins = 0; | ||||
| //    for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_) | ||||
| //        { | ||||
| //            frequency_bins++; | ||||
| //        } | ||||
| //    DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; | ||||
| //    unsigned int ncells = vector_length_ * frequency_bins; | ||||
| //    double exponent = 1.0 / static_cast<double>(ncells); | ||||
| //    double val = pow(1.0 - pfa, exponent); | ||||
| //    double lambda = double(vector_length_); | ||||
| //    boost::math::exponential_distribution<double> mydist(lambda); | ||||
| //    float threshold = static_cast<float>(quantile(mydist, val)); | ||||
| // | ||||
| //    return threshold; | ||||
| //} | ||||
|  | ||||
|  | ||||
| void GpsL5iPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); | ||||
| //            top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); | ||||
| //            top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); | ||||
| //            top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
| //        } | ||||
|     // nothing to connect | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL5iPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) | ||||
| { | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            // Since a byte-based acq implementation is not available, | ||||
| //            // we just convert cshorts to gr_complex | ||||
| //            top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); | ||||
| //            top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); | ||||
| //            top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); | ||||
| //            top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
| //        } | ||||
|     // nothing to disconnect | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GpsL5iPcpsAcquisitionFpga::get_left_block() | ||||
| { | ||||
| //    if (item_type_.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            return stream_to_vector_; | ||||
| //        } | ||||
| //    else if (item_type_.compare("cshort") == 0) | ||||
| //        { | ||||
| //            return stream_to_vector_; | ||||
| //        } | ||||
| //    else if (item_type_.compare("cbyte") == 0) | ||||
| //        { | ||||
| //            return cbyte_to_float_x2_; | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            LOG(WARNING) << item_type_ << " unknown acquisition item type"; | ||||
| //            return nullptr; | ||||
| //        } | ||||
|     return nullptr; | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GpsL5iPcpsAcquisitionFpga::get_right_block() | ||||
| { | ||||
|     return acquisition_fpga_; | ||||
| } | ||||
| @@ -0,0 +1,171 @@ | ||||
| /*! | ||||
|  * \file GPS_L5i_PCPS_Acquisition.h | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  GPS L5i signals | ||||
|  * \authors <ul> | ||||
|  *          <li> Javier Arribas, 2017. jarribas(at)cttc.es | ||||
|  *          </ul> | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * 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 <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_FPGA_H_ | ||||
| #define GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_FPGA_H_ | ||||
|  | ||||
| #include "acquisition_interface.h" | ||||
| #include "gnss_synchro.h" | ||||
| #include "pcps_acquisition_fpga.h" | ||||
| #include "complex_byte_to_float_x2.h" | ||||
| #include <gnuradio/blocks/stream_to_vector.h> | ||||
| #include <gnuradio/blocks/float_to_complex.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr.h> | ||||
| #include <string> | ||||
|  | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| /*! | ||||
|  * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface | ||||
|  *  for GPS L5i signals | ||||
|  */ | ||||
| class GpsL5iPcpsAcquisitionFpga : public AcquisitionInterface | ||||
| { | ||||
| public: | ||||
|     GpsL5iPcpsAcquisitionFpga(ConfigurationInterface* configuration, | ||||
|         std::string role, unsigned int in_streams, | ||||
|         unsigned int out_streams); | ||||
|  | ||||
|     virtual ~GpsL5iPcpsAcquisitionFpga(); | ||||
|  | ||||
|     inline std::string role() override | ||||
|     { | ||||
|         return role_; | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns "GPS_L5i_PCPS_Acquisition" | ||||
|      */ | ||||
|     inline std::string implementation() override | ||||
|     { | ||||
|         return "GPS_L5i_PCPS_Acquisition"; | ||||
|     } | ||||
|  | ||||
|     inline size_t item_size() override | ||||
|     { | ||||
|         return item_size_; | ||||
|     } | ||||
|  | ||||
|     void connect(gr::top_block_sptr top_block) override; | ||||
|     void disconnect(gr::top_block_sptr top_block) override; | ||||
|     gr::basic_block_sptr get_left_block() override; | ||||
|     gr::basic_block_sptr get_right_block() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition/tracking common Gnss_Synchro object pointer | ||||
|      * to efficiently exchange synchronization data between acquisition and | ||||
|      *  tracking blocks | ||||
|      */ | ||||
|     void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition channel unique ID | ||||
|      */ | ||||
|     void set_channel(unsigned int channel) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set statistics threshold of PCPS algorithm | ||||
|      */ | ||||
|     void set_threshold(float threshold) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set maximum Doppler off grid search | ||||
|      */ | ||||
|     void set_doppler_max(unsigned int doppler_max) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set Doppler steps for the grid search | ||||
|      */ | ||||
|     void set_doppler_step(unsigned int doppler_step) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Initializes acquisition algorithm. | ||||
|      */ | ||||
|     void init() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Sets local code for GPS L2/M PCPS acquisition algorithm. | ||||
|      */ | ||||
|     void set_local_code() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Returns the maximum peak of grid search | ||||
|      */ | ||||
|     signed int mag() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Restart acquisition algorithm | ||||
|      */ | ||||
|     void reset() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief If state = 1, it forces the block to start acquiring from the first sample | ||||
|      */ | ||||
|     void set_state(int state) override; | ||||
|  | ||||
| private: | ||||
|     ConfigurationInterface* configuration_; | ||||
|     //pcps_acquisition_sptr acquisition_; | ||||
|     pcps_acquisition_fpga_sptr acquisition_fpga_; | ||||
|     gr::blocks::stream_to_vector::sptr stream_to_vector_; | ||||
|     gr::blocks::float_to_complex::sptr float_to_complex_; | ||||
|     complex_byte_to_float_x2_sptr cbyte_to_float_x2_; | ||||
|     size_t item_size_; | ||||
|     std::string item_type_; | ||||
|     unsigned int vector_length_; | ||||
|     unsigned int code_length_; | ||||
|     bool bit_transition_flag_; | ||||
|     bool use_CFAR_algorithm_flag_; | ||||
|     unsigned int channel_; | ||||
|     float threshold_; | ||||
|     unsigned int doppler_max_; | ||||
|     unsigned int doppler_step_; | ||||
|     unsigned int max_dwells_; | ||||
|     long fs_in_; | ||||
|     //long if_; | ||||
|     bool dump_; | ||||
|     bool blocking_; | ||||
|     std::string dump_filename_; | ||||
|     std::complex<float>* code_; | ||||
|     Gnss_Synchro* gnss_synchro_; | ||||
|     std::string role_; | ||||
|     unsigned int in_streams_; | ||||
|     unsigned int out_streams_; | ||||
|  | ||||
|     lv_16sc_t* d_all_fft_codes_;  // memory that contains all the code ffts | ||||
|  | ||||
|     float calculate_threshold(float pfa); | ||||
| }; | ||||
|  | ||||
| #endif /* GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_FPGA_H_ */ | ||||
| @@ -15,7 +15,7 @@ | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2017  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -33,16 +33,19 @@ | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "pcps_acquisition_fpga.h" | ||||
|  | ||||
| #include <glog/logging.h> | ||||
| #include <gnuradio/io_signature.h> | ||||
| #include "pcps_acquisition_fpga.h" | ||||
|  | ||||
|  | ||||
| #define AQ_DOWNSAMPLING_DELAY 40  // delay due to the downsampling filter in the acquisition | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_) | ||||
| @@ -55,13 +58,15 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_) : gr::block( | ||||
|                                                                           gr::io_signature::make(0, 0, 0), | ||||
|                                                                           gr::io_signature::make(0, 0, 0)) | ||||
| { | ||||
|     //   printf("acq constructor start\n"); | ||||
|     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_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms; | ||||
|     d_fft_size = acq_parameters.samples_per_code; | ||||
|     d_mag = 0; | ||||
|     d_input_power = 0.0; | ||||
|     d_num_doppler_bins = 0; | ||||
| @@ -71,25 +76,49 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_) : gr::block( | ||||
|     d_channel = 0; | ||||
|     d_gnss_synchro = 0; | ||||
|  | ||||
|     acquisition_fpga = std::make_shared<fpga_acquisition>(acq_parameters.device_name, d_fft_size, acq_parameters.doppler_max, acq_parameters.samples_per_ms, | ||||
|     //printf("zzzz acq_parameters.code_length = %d\n", acq_parameters.code_length); | ||||
|     //printf("zzzz acq_parameters.samples_per_ms = %d\n", acq_parameters.samples_per_ms); | ||||
|     //printf("zzzz d_fft_size = %d\n", d_fft_size); | ||||
|  | ||||
|     // this one works we don't know why | ||||
|     //    acquisition_fpga = std::make_shared <fpga_acquisition> | ||||
|     //          (acq_parameters.device_name, acq_parameters.code_length, acq_parameters.doppler_max, acq_parameters.samples_per_ms, | ||||
|     //                  acq_parameters.fs_in, acq_parameters.freq, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes); | ||||
|  | ||||
|     // this one is the one it should be but it doesn't work | ||||
|     acquisition_fpga = std::make_shared<fpga_acquisition>(acq_parameters.device_name, acq_parameters.code_length, acq_parameters.doppler_max, d_fft_size, | ||||
|         acq_parameters.fs_in, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes); | ||||
|  | ||||
|     //    acquisition_fpga = std::make_shared <fpga_acquisition> | ||||
|     //          (acq_parameters.device_name, acq_parameters.samples_per_code, acq_parameters.doppler_max, acq_parameters.samples_per_code, | ||||
|     //                  acq_parameters.fs_in, acq_parameters.freq, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes); | ||||
|  | ||||
|     // debug | ||||
|     //debug_d_max_absolute = 0.0; | ||||
|     //debug_d_input_power_absolute = 0.0; | ||||
|     //  printf("acq constructor end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| pcps_acquisition_fpga::~pcps_acquisition_fpga() | ||||
| { | ||||
|     //  printf("acq destructor start\n"); | ||||
|     acquisition_fpga->free(); | ||||
|     //  printf("acq destructor end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void pcps_acquisition_fpga::set_local_code() | ||||
| { | ||||
|     //   printf("acq set local code start\n"); | ||||
|     acquisition_fpga->set_local_code(d_gnss_synchro->PRN); | ||||
|     //   printf("acq set local code end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void pcps_acquisition_fpga::init() | ||||
| { | ||||
|     //  printf("acq init start\n"); | ||||
|     d_gnss_synchro->Flag_valid_acquisition = false; | ||||
|     d_gnss_synchro->Flag_valid_symbol_output = false; | ||||
|     d_gnss_synchro->Flag_valid_pseudorange = false; | ||||
| @@ -102,11 +131,13 @@ void pcps_acquisition_fpga::init() | ||||
|     d_num_doppler_bins = static_cast<uint32_t>(std::ceil(static_cast<double>(static_cast<int32_t>(acq_parameters.doppler_max) - static_cast<int32_t>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step))); | ||||
|  | ||||
|     acquisition_fpga->init(); | ||||
|     //  printf("acq init end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void pcps_acquisition_fpga::set_state(int32_tstate) | ||||
| void pcps_acquisition_fpga::set_state(int32_t state) | ||||
| { | ||||
|     //   printf("acq set state start\n"); | ||||
|     d_state = state; | ||||
|     if (d_state == 1) | ||||
|         { | ||||
| @@ -126,11 +157,13 @@ void pcps_acquisition_fpga::set_state(int32_tstate) | ||||
|         { | ||||
|             LOG(ERROR) << "State can only be set to 0 or 1"; | ||||
|         } | ||||
|     //   printf("acq set state end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void pcps_acquisition_fpga::send_positive_acquisition() | ||||
| { | ||||
|     //    printf("acq send positive acquisition start\n"); | ||||
|     // 6.1- Declare positive acquisition using a message port | ||||
|     //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL | ||||
|     DLOG(INFO) << "positive acquisition" | ||||
| @@ -144,11 +177,13 @@ void pcps_acquisition_fpga::send_positive_acquisition() | ||||
|                << ", input signal power " << d_input_power; | ||||
|  | ||||
|     this->message_port_pub(pmt::mp("events"), pmt::from_long(1)); | ||||
|     //    printf("acq send positive acquisition end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void pcps_acquisition_fpga::send_negative_acquisition() | ||||
| { | ||||
|     //   printf("acq send negative acquisition start\n"); | ||||
|     // 6.2- Declare negative acquisition using a message port | ||||
|     //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL | ||||
|     DLOG(INFO) << "negative acquisition" | ||||
| @@ -162,16 +197,19 @@ void pcps_acquisition_fpga::send_negative_acquisition() | ||||
|                << ", input signal power " << d_input_power; | ||||
|  | ||||
|     this->message_port_pub(pmt::mp("events"), pmt::from_long(2)); | ||||
|     //    printf("acq send negative acquisition end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void pcps_acquisition_fpga::set_active(bool active) | ||||
| { | ||||
|     //   printf("acq set active start\n"); | ||||
|     d_active = active; | ||||
|  | ||||
|     // initialize acquisition algorithm | ||||
|     uint32_t indext = 0; | ||||
|     float magt = 0.0; | ||||
|     float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size); | ||||
|  | ||||
|     d_input_power = 0.0; | ||||
|     d_mag = 0.0; | ||||
| @@ -184,24 +222,32 @@ void pcps_acquisition_fpga::set_active(bool active) | ||||
|                // no CFAR algorithm in the FPGA | ||||
|                << ", use_CFAR_algorithm_flag: false"; | ||||
|  | ||||
|     uint32_t initial_sample; | ||||
|     uint64_t initial_sample; | ||||
|     float input_power_all = 0.0; | ||||
|     float input_power_computed = 0.0; | ||||
|     for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) | ||||
|  | ||||
|     float temp_d_input_power; | ||||
|  | ||||
|     // loop through acquisition | ||||
|     /* | ||||
|     for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) | ||||
|         { | ||||
|             // doppler search steps | ||||
|             int32_tdoppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * doppler_index; | ||||
|             int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * doppler_index; | ||||
|  | ||||
|             acquisition_fpga->set_phase_step(doppler_index); | ||||
|             //acquisition_fpga->set_phase_step(doppler_index); | ||||
|             acquisition_fpga->set_doppler_sweep_debug(1, doppler_index); | ||||
|             acquisition_fpga->run_acquisition(); // runs acquisition and waits until it is finished | ||||
|             acquisition_fpga->read_acquisition_results(&indext, &magt, | ||||
|                 &initial_sample, &d_input_power); | ||||
|             d_sample_counter = static_cast<uint64_t>(initial_sample); | ||||
|                     &initial_sample, &d_input_power, &d_doppler_index); | ||||
|             d_sample_counter = initial_sample; | ||||
|  | ||||
|             if (d_mag < magt) | ||||
|                 { | ||||
|                     d_mag = magt; | ||||
|  | ||||
|                     temp_d_input_power = d_input_power; | ||||
|  | ||||
|                     input_power_all = d_input_power / (d_fft_size - 1); | ||||
|                     input_power_computed = (d_input_power - d_mag) / (d_fft_size - 1); | ||||
|                     d_input_power = (d_input_power - d_mag) / (d_fft_size - 1); | ||||
| @@ -216,10 +262,73 @@ void pcps_acquisition_fpga::set_active(bool active) | ||||
|             // In the case of the FPGA the option of dumping the results of the acquisition to a file is not available | ||||
|             // because the IFFT vector is not available | ||||
|         } | ||||
| */ | ||||
|  | ||||
|     // debug | ||||
|     //acquisition_fpga->block_samples(); | ||||
|  | ||||
|     // run loop in hw | ||||
|     //printf("LAUNCH ACQ\n"); | ||||
|     acquisition_fpga->set_doppler_sweep(d_num_doppler_bins); | ||||
|     acquisition_fpga->run_acquisition(); | ||||
|     acquisition_fpga->read_acquisition_results(&indext, &magt, | ||||
|         &initial_sample, &d_input_power, &d_doppler_index); | ||||
|     //printf("READ ACQ RESULTS\n"); | ||||
|  | ||||
|     // debug | ||||
|     //acquisition_fpga->unblock_samples(); | ||||
|  | ||||
|     d_mag = magt; | ||||
|  | ||||
|  | ||||
|     // debug | ||||
|     debug_d_max_absolute = magt; | ||||
|     debug_d_input_power_absolute = d_input_power; | ||||
|     debug_indext = indext; | ||||
|     debug_doppler_index = d_doppler_index; | ||||
|  | ||||
|     //  temp_d_input_power = d_input_power; | ||||
|  | ||||
|     d_input_power = (d_input_power - d_mag) / (d_fft_size - 1); | ||||
|     int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * d_doppler_index; | ||||
|     //d_gnss_synchro->Acq_delay_samples = static_cast<double>(2*(indext % (2*acq_parameters.samples_per_code))); | ||||
|     d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code); | ||||
|     d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); | ||||
|     d_sample_counter = initial_sample; | ||||
|     //d_gnss_synchro->Acq_samplestamp_samples = 2*d_sample_counter - 81; // delay due to the downsampling filter in the acquisition | ||||
|     //d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter - 40; // delay due to the downsampling filter in the acquisition | ||||
|     d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;  // delay due to the downsampling filter in the acquisition | ||||
|     d_test_statistics = (d_mag / d_input_power);                 //* correction_factor; | ||||
|  | ||||
|     // debug | ||||
|     //    if (d_gnss_synchro->Acq_delay_samples > acq_parameters.code_length) | ||||
|     //        { | ||||
|     //            printf("d_gnss_synchro->Acq_samplestamp_samples = %d\n", d_gnss_synchro->Acq_samplestamp_samples); | ||||
|     //            printf("d_gnss_synchro->Acq_delay_samples = %f\n", d_gnss_synchro->Acq_delay_samples); | ||||
|     //        } | ||||
|  | ||||
|     // if (temp_d_input_power > debug_d_input_power_absolute) | ||||
|     //     { | ||||
|     //         debug_d_max_absolute = d_mag; | ||||
|     //         debug_d_input_power_absolute = temp_d_input_power; | ||||
|     //     } | ||||
|     // printf ("max debug_d_max_absolute = %f\n", debug_d_max_absolute); | ||||
|     // printf ("debug_d_input_power_absolute = %f\n", debug_d_input_power_absolute); | ||||
|  | ||||
|     //    printf("&&&&& d_test_statistics = %f\n", d_test_statistics); | ||||
|     //    printf("&&&&& debug_d_max_absolute =%f\n",debug_d_max_absolute); | ||||
|     //    printf("&&&&& debug_d_input_power_absolute =%f\n",debug_d_input_power_absolute); | ||||
|     //    printf("&&&&& debug_indext = %d\n",debug_indext); | ||||
|     //    printf("&&&&& debug_doppler_index = %d\n",debug_doppler_index); | ||||
|  | ||||
|     if (d_test_statistics > d_threshold) | ||||
|         { | ||||
|             d_active = false; | ||||
|             //            printf("##### d_test_statistics = %f\n", d_test_statistics); | ||||
|             //            printf("##### debug_d_max_absolute =%f\n",debug_d_max_absolute); | ||||
|             //            printf("##### debug_d_input_power_absolute =%f\n",debug_d_input_power_absolute); | ||||
|             //            printf("##### initial_sample = %llu\n",initial_sample); | ||||
|             //            printf("##### debug_doppler_index = %d\n",debug_doppler_index); | ||||
|             send_positive_acquisition(); | ||||
|             d_state = 0;  // Positive acquisition | ||||
|         } | ||||
| @@ -229,12 +338,13 @@ void pcps_acquisition_fpga::set_active(bool active) | ||||
|             d_active = false; | ||||
|             send_negative_acquisition(); | ||||
|         } | ||||
|  | ||||
|     //   printf("acq set active end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| int pcps_acquisition_fpga::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_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 | ||||
|   | ||||
| @@ -66,10 +66,10 @@ typedef struct | ||||
|     /* pcps acquisition configuration */ | ||||
|     uint32_t sampled_ms; | ||||
|     uint32_t doppler_max; | ||||
|     int64_t freq; | ||||
|     int64_t fs_in; | ||||
|     int32_tsamples_per_ms; | ||||
|     int32_tsamples_per_code; | ||||
|     int32_t samples_per_ms; | ||||
|     int32_t samples_per_code; | ||||
|     int32_t code_length; | ||||
|     uint32_t select_queue_Fpga; | ||||
|     std::string device_name; | ||||
|     lv_16sc_t* all_fft_codes;  // memory that contains all the code ffts | ||||
| @@ -107,8 +107,9 @@ private: | ||||
|     float d_threshold; | ||||
|     float d_mag; | ||||
|     float d_input_power; | ||||
|     uint32_t d_doppler_index; | ||||
|     float d_test_statistics; | ||||
|     int32_td_state; | ||||
|     int32_t d_state; | ||||
|     uint32_t d_channel; | ||||
|     uint32_t d_doppler_step; | ||||
|     uint32_t d_fft_size; | ||||
| @@ -117,6 +118,12 @@ private: | ||||
|     Gnss_Synchro* d_gnss_synchro; | ||||
|     std::shared_ptr<fpga_acquisition> acquisition_fpga; | ||||
|  | ||||
|     // debug | ||||
|     float debug_d_max_absolute; | ||||
|     float debug_d_input_power_absolute; | ||||
|     int32_t debug_indext; | ||||
|     int32_t debug_doppler_index; | ||||
|  | ||||
| public: | ||||
|     ~pcps_acquisition_fpga(); | ||||
|  | ||||
| @@ -127,7 +134,9 @@ public: | ||||
|       */ | ||||
|     inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) | ||||
|     { | ||||
|         //    printf("acq set gnss synchro start\n"); | ||||
|         d_gnss_synchro = p_gnss_synchro; | ||||
|         //   printf("acq set gnss synchro end\n"); | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
| @@ -135,7 +144,9 @@ public: | ||||
|      */ | ||||
|     inline uint32_t mag() const | ||||
|     { | ||||
|         //   printf("acq dmag start\n"); | ||||
|         return d_mag; | ||||
|         //   printf("acq dmag end\n"); | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
| @@ -154,7 +165,7 @@ public: | ||||
|       * first available sample. | ||||
|       * \param state - int=1 forces start of acquisition | ||||
|       */ | ||||
|     void set_state(int32_tstate); | ||||
|     void set_state(int32_t state); | ||||
|  | ||||
|     /*! | ||||
|       * \brief Starts acquisition algorithm, turning from standby mode to | ||||
| @@ -179,7 +190,9 @@ public: | ||||
|       */ | ||||
|     inline void set_threshold(float threshold) | ||||
|     { | ||||
|         //    printf("acq set threshold start\n"); | ||||
|         d_threshold = threshold; | ||||
|         //   printf("acq set threshold end\n"); | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
| @@ -188,8 +201,10 @@ public: | ||||
|       */ | ||||
|     inline void set_doppler_max(uint32_t doppler_max) | ||||
|     { | ||||
|         //   printf("acq set doppler max start\n"); | ||||
|         acq_parameters.doppler_max = doppler_max; | ||||
|         acquisition_fpga->set_doppler_max(doppler_max); | ||||
|         //    printf("acq set doppler max end\n"); | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
| @@ -198,8 +213,10 @@ public: | ||||
|       */ | ||||
|     inline void set_doppler_step(uint32_t doppler_step) | ||||
|     { | ||||
|         //   printf("acq set doppler step start\n"); | ||||
|         d_doppler_step = doppler_step; | ||||
|         acquisition_fpga->set_doppler_step(doppler_step); | ||||
|         //   printf("acq set doppler step end\n"); | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
|   | ||||
| @@ -33,20 +33,21 @@ | ||||
| #define GNSS_SDR_ACQ_CONF_H_ | ||||
|  | ||||
| #include <cstddef> | ||||
| #include <cstdint> | ||||
| #include <string> | ||||
|  | ||||
| class Acq_Conf | ||||
| { | ||||
| public: | ||||
|     /* PCPS Acquisition configuration */ | ||||
|     unsigned int sampled_ms; | ||||
|     unsigned int ms_per_code; | ||||
|     unsigned int samples_per_chip; | ||||
|     unsigned int max_dwells; | ||||
|     unsigned int doppler_max; | ||||
|     unsigned int num_doppler_bins_step2; | ||||
|     uint32_t sampled_ms; | ||||
|     uint32_t ms_per_code; | ||||
|     uint32_t samples_per_chip; | ||||
|     uint32_t max_dwells; | ||||
|     uint32_t doppler_max; | ||||
|     uint32_t num_doppler_bins_step2; | ||||
|     float doppler_step2; | ||||
|     long fs_in; | ||||
|     int64_t fs_in; | ||||
|     float samples_per_ms; | ||||
|     float samples_per_code; | ||||
|     bool bit_transition_flag; | ||||
| @@ -56,7 +57,7 @@ public: | ||||
|     bool blocking_on_standby;  // enable it only for unit testing to avoid sample consume on idle status | ||||
|     bool make_2_steps; | ||||
|     std::string dump_filename; | ||||
|     unsigned int dump_channel; | ||||
|     uint32_t dump_channel; | ||||
|     size_t it_size; | ||||
|  | ||||
|     Acq_Conf(); | ||||
|   | ||||
| @@ -37,6 +37,7 @@ | ||||
| #include "GPS_L1_CA.h" | ||||
| #include "gps_sdr_signal_processing.h" | ||||
| #include <glog/logging.h> | ||||
| #include <iostream> | ||||
| #include <fcntl.h>     // libraries used by the GIPO | ||||
| #include <sys/mman.h>  // libraries used by the GIPO | ||||
|  | ||||
| @@ -55,6 +56,17 @@ | ||||
| #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 | ||||
|  | ||||
| // 12-bits | ||||
| //#define SELECT_LSBits 0x0FFF | ||||
| //#define SELECT_MSBbits 0x00FFF000 | ||||
| //#define SELECT_24_BITS 0x00FFFFFF | ||||
| //#define SHL_12_BITS 4096 | ||||
| // 16-bits | ||||
| #define SELECT_LSBits 0x0FFFF | ||||
| #define SELECT_MSBbits 0xFFFF0000 | ||||
| #define SELECT_32_BITS 0xFFFFFFFF | ||||
| #define SHL_16_BITS 65536 | ||||
|  | ||||
|  | ||||
| bool fpga_acquisition::init() | ||||
| { | ||||
| @@ -69,6 +81,10 @@ bool fpga_acquisition::set_local_code(uint32_t PRN) | ||||
|     // select the code with the chosen PRN | ||||
|     fpga_acquisition::fpga_configure_acquisition_local_code( | ||||
|         &d_all_fft_codes[d_nsamples_total * (PRN - 1)]); | ||||
|  | ||||
|     //fpga_acquisition::fpga_configure_acquisition_local_code( | ||||
|     //    &d_all_fft_codes[0]); | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| @@ -80,9 +96,14 @@ fpga_acquisition::fpga_acquisition(std::string device_name, | ||||
|     uint32_t sampled_ms, uint32_t select_queue, | ||||
|     lv_16sc_t *all_fft_codes) | ||||
| { | ||||
|     uint32_t vector_length = nsamples_total * sampled_ms; | ||||
|     //printf("AAA- sampled_ms = %d\n ", sampled_ms); | ||||
|  | ||||
|     uint32_t vector_length = nsamples_total;  // * sampled_ms; | ||||
|  | ||||
|     //printf("AAA- vector_length = %d\n ", vector_length); | ||||
|     // 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 | ||||
| @@ -98,6 +119,7 @@ fpga_acquisition::fpga_acquisition(std::string device_name, | ||||
|     if ((d_fd = open(d_device_name.c_str(), O_RDWR | O_SYNC)) == -1) | ||||
|         { | ||||
|             LOG(WARNING) << "Cannot open deviceio" << d_device_name; | ||||
|             std::cout << "Acq: cannot open deviceio" << d_device_name << std::endl; | ||||
|         } | ||||
|     d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(NULL, PAGE_SIZE, | ||||
|         PROT_READ | PROT_WRITE, MAP_SHARED, d_fd, 0)); | ||||
| @@ -105,6 +127,7 @@ fpga_acquisition::fpga_acquisition(std::string device_name, | ||||
|     if (d_map_base == reinterpret_cast<void *>(-1)) | ||||
|         { | ||||
|             LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory"; | ||||
|             std::cout << "Acq: cannot map deviceio" << d_device_name << std::endl; | ||||
|         } | ||||
|  | ||||
|     // sanity check : check test register | ||||
| @@ -118,6 +141,7 @@ fpga_acquisition::fpga_acquisition(std::string device_name, | ||||
|     else | ||||
|         { | ||||
|             LOG(INFO) << "Acquisition test register sanity check success!"; | ||||
|             //std::cout << "Acquisition test register sanity check success!" << std::endl; | ||||
|         } | ||||
|     fpga_acquisition::reset_acquisition(); | ||||
|     DLOG(INFO) << "Acquisition FPGA class created"; | ||||
| @@ -150,20 +174,35 @@ uint32_t fpga_acquisition::fpga_acquisition_test_register(uint32_t writeval) | ||||
|  | ||||
| void fpga_acquisition::fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]) | ||||
| { | ||||
|     uint16_t local_code; | ||||
|     uint32_t local_code; | ||||
|     uint32_t k, tmp, tmp2; | ||||
|     uint32_t fft_data; | ||||
|  | ||||
|     // clear memory address counter | ||||
|     d_map_base[4] = LOCAL_CODE_CLEAR_MEM; | ||||
|     //d_map_base[6] = LOCAL_CODE_CLEAR_MEM; | ||||
|     d_map_base[9] = 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; | ||||
|             //tmp = k; | ||||
|             //tmp2 = k; | ||||
|  | ||||
|             //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); | ||||
|             //local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_12_BITS) & SELECT_MSBbits);  // put together the real part and the imaginary part | ||||
|             local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_16_BITS) & SELECT_MSBbits);  // put together the real part and the imaginary part | ||||
|             //fft_data = MEM_LOCAL_CODE_WR_ENABLE | (local_code & SELECT_24_BITS); | ||||
|             fft_data = local_code & SELECT_32_BITS; | ||||
|             d_map_base[6] = fft_data; | ||||
|  | ||||
|  | ||||
|             //printf("debug local code %d real = %d imag = %d local_code = %d fft_data = %d\n", k, tmp, tmp2, local_code, fft_data); | ||||
|             //printf("debug local code %d real = 0x%08X imag = 0x%08X local_code = 0x%08X fft_data = 0x%08X\n", k, tmp, tmp2, local_code, fft_data); | ||||
|         } | ||||
|     //printf("d_vector_length = %d\n", d_vector_length); | ||||
|     //while(1); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -173,12 +212,14 @@ void fpga_acquisition::run_acquisition(void) | ||||
|     int32_t reenable = 1; | ||||
|     write(d_fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t)); | ||||
|     // launch the acquisition process | ||||
|     d_map_base[6] = LAUNCH_ACQUISITION;  // writing anything to reg 6 launches the acquisition process | ||||
|     //printf("launchin acquisition ...\n"); | ||||
|     d_map_base[8] = LAUNCH_ACQUISITION;  // writing a 1 to reg 8 launches the acquisition process | ||||
|  | ||||
|     int32_t irq_count; | ||||
|     ssize_t nb; | ||||
|     // wait for interrupt | ||||
|     nb = read(d_fd, &irq_count, sizeof(irq_count)); | ||||
|     //printf("interrupt received\n"); | ||||
|     if (nb != sizeof(irq_count)) | ||||
|         { | ||||
|             printf("acquisition module Read failed to retrieve 4 bytes!\n"); | ||||
| @@ -187,12 +228,111 @@ void fpga_acquisition::run_acquisition(void) | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_acquisition::set_doppler_sweep(uint32_t num_sweeps) | ||||
| { | ||||
|     float phase_step_rad_real; | ||||
|     float phase_step_rad_int_temp; | ||||
|     int32_t phase_step_rad_int; | ||||
|     //int32_t doppler = static_cast<int32_t>(-d_doppler_max) + d_doppler_step * doppler_index; | ||||
|     int32_t doppler = static_cast<int32_t>(-d_doppler_max); | ||||
|     //float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in); | ||||
|     float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in); | ||||
|     // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing | ||||
|     // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) | ||||
|     // The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x) | ||||
|     // while the gnss-sdr software (volk_gnsssdr_s32f_sincos_32fc) generates cos(x) + j*sin(x) | ||||
|     phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); | ||||
|     // avoid saturation of the fixed point representation in the fpga | ||||
|     // (only the positive value can saturate due to the 2's complement representation) | ||||
|  | ||||
|     //printf("AAA  phase_step_rad_real for initial doppler = %f\n", phase_step_rad_real); | ||||
|     if (phase_step_rad_real >= 1.0) | ||||
|         { | ||||
|             phase_step_rad_real = MAX_PHASE_STEP_RAD; | ||||
|         } | ||||
|     //printf("AAA  phase_step_rad_real for initial doppler after checking = %f\n", phase_step_rad_real); | ||||
|     phase_step_rad_int_temp = phase_step_rad_real * POW_2_2;                          // * 2^2 | ||||
|     phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29));  // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings | ||||
|     //printf("AAA writing phase_step_rad_int for initial doppler = %d to d map base 3\n", phase_step_rad_int); | ||||
|     d_map_base[3] = phase_step_rad_int; | ||||
|  | ||||
|     // repeat the calculation with the doppler step | ||||
|     doppler = static_cast<int32_t>(d_doppler_step); | ||||
|     phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in); | ||||
|     phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); | ||||
|     //printf("AAA  phase_step_rad_real for doppler step = %f\n", phase_step_rad_real); | ||||
|     if (phase_step_rad_real >= 1.0) | ||||
|         { | ||||
|             phase_step_rad_real = MAX_PHASE_STEP_RAD; | ||||
|         } | ||||
|     //printf("AAA  phase_step_rad_real for doppler step after checking = %f\n", phase_step_rad_real); | ||||
|     phase_step_rad_int_temp = phase_step_rad_real * POW_2_2;                          // * 2^2 | ||||
|     phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29));  // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings | ||||
|     //printf("AAA writing phase_step_rad_int for doppler step = %d to d map base 4\n", phase_step_rad_int); | ||||
|     d_map_base[4] = phase_step_rad_int; | ||||
|     //printf("AAA writing num sweeps to d map base 5 = %d\n", num_sweeps); | ||||
|     d_map_base[5] = num_sweeps; | ||||
| } | ||||
|  | ||||
| void fpga_acquisition::set_doppler_sweep_debug(uint32_t num_sweeps, uint32_t doppler_index) | ||||
| { | ||||
|     float phase_step_rad_real; | ||||
|     float phase_step_rad_int_temp; | ||||
|     int32_t phase_step_rad_int; | ||||
|     int32_t doppler = -static_cast<int32_t>(d_doppler_max) + d_doppler_step * doppler_index; | ||||
|     //int32_t doppler = static_cast<int32_t>(-d_doppler_max); | ||||
|     //float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in); | ||||
|     float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in); | ||||
|     // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing | ||||
|     // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) | ||||
|     // The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x) | ||||
|     // while the gnss-sdr software (volk_gnsssdr_s32f_sincos_32fc) generates cos(x) + j*sin(x) | ||||
|     phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); | ||||
|     // avoid saturation of the fixed point representation in the fpga | ||||
|     // (only the positive value can saturate due to the 2's complement representation) | ||||
|  | ||||
|     //printf("AAAh  phase_step_rad_real for initial doppler = %f\n", phase_step_rad_real); | ||||
|     if (phase_step_rad_real >= 1.0) | ||||
|         { | ||||
|             phase_step_rad_real = MAX_PHASE_STEP_RAD; | ||||
|         } | ||||
|     //printf("AAAh  phase_step_rad_real for initial doppler after checking = %f\n", phase_step_rad_real); | ||||
|     phase_step_rad_int_temp = phase_step_rad_real * POW_2_2;                          // * 2^2 | ||||
|     phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29));  // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings | ||||
|     //printf("AAAh writing phase_step_rad_int for initial doppler = %d to d map base 3\n", phase_step_rad_int); | ||||
|     d_map_base[3] = phase_step_rad_int; | ||||
|  | ||||
|     // repeat the calculation with the doppler step | ||||
|     doppler = static_cast<int32_t>(d_doppler_step); | ||||
|     phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in); | ||||
|     phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); | ||||
|     //printf("AAAh  phase_step_rad_real for doppler step = %f\n", phase_step_rad_real); | ||||
|     if (phase_step_rad_real >= 1.0) | ||||
|         { | ||||
|             phase_step_rad_real = MAX_PHASE_STEP_RAD; | ||||
|         } | ||||
|     //printf("AAAh  phase_step_rad_real for doppler step after checking = %f\n", phase_step_rad_real); | ||||
|     phase_step_rad_int_temp = phase_step_rad_real * POW_2_2;                          // * 2^2 | ||||
|     phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29));  // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings | ||||
|     //printf("AAAh writing phase_step_rad_int for doppler step = %d to d map base 4\n", phase_step_rad_int); | ||||
|     d_map_base[4] = phase_step_rad_int; | ||||
|     //printf("AAAh writing num sweeps to d map base 5 = %d\n", num_sweeps); | ||||
|     d_map_base[5] = num_sweeps; | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_acquisition::configure_acquisition() | ||||
| { | ||||
|     //printf("AAA d_select_queue = %d\n", d_select_queue); | ||||
|     d_map_base[0] = d_select_queue; | ||||
|     //printf("AAA writing d_vector_length = %d to d map base 1\n ", d_vector_length); | ||||
|     d_map_base[1] = d_vector_length; | ||||
|     //printf("AAA writing d_nsamples = %d to d map base 2\n ", d_nsamples); | ||||
|     d_map_base[2] = d_nsamples; | ||||
|     d_map_base[5] = static_cast<int32_t>(log2(static_cast<float>(d_vector_length)));  // log2 FFTlength | ||||
|     //printf("AAA writing LOG2 d_vector_length = %d to d map base 7\n ", (int)log2((float)d_vector_length)); | ||||
|     d_map_base[7] = static_cast<int32_t>(log2(static_cast<float>(d_vector_length)));  // log2 FFTlength | ||||
|     //printf("acquisition debug vector length = %d\n", d_vector_length); | ||||
|     //printf("acquisition debug vector length = %d\n", (int)log2((float)d_vector_length)); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -201,8 +341,9 @@ void fpga_acquisition::set_phase_step(uint32_t doppler_index) | ||||
|     float phase_step_rad_real; | ||||
|     float phase_step_rad_int_temp; | ||||
|     int32_t phase_step_rad_int; | ||||
|     int32_t doppler = static_cast<int>(-d_doppler_max) + d_doppler_step * doppler_index; | ||||
|     float phase_step_rad = GPS_TWO_PI * doppler / static_cast<float>(d_fs_in); | ||||
|     int32_t doppler = -static_cast<int32_t>(d_doppler_max) + d_doppler_step * doppler_index; | ||||
|     //float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in); | ||||
|     float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast<float>(d_fs_in); | ||||
|     // 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) | ||||
| @@ -210,28 +351,46 @@ void fpga_acquisition::set_phase_step(uint32_t doppler_index) | ||||
|     phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); | ||||
|     // avoid saturation of the fixed point representation in the fpga | ||||
|     // (only the positive value can saturate due to the 2's complement representation) | ||||
|     //printf("AAA+ phase_step_rad_real = %f\n", phase_step_rad_real); | ||||
|     if (phase_step_rad_real >= 1.0) | ||||
|         { | ||||
|             phase_step_rad_real = MAX_PHASE_STEP_RAD; | ||||
|         } | ||||
|     //printf("AAA+ phase_step_rad_real after checking = %f\n", phase_step_rad_real); | ||||
|     phase_step_rad_int_temp = phase_step_rad_real * POW_2_2;                          // * 2^2 | ||||
|     phase_step_rad_int = (int32_t)(phase_step_rad_int_temp * (POW_2_29));  // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings | ||||
|     phase_step_rad_int = static_cast<int32_t>(phase_step_rad_int_temp * (POW_2_29));  // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings | ||||
|     //printf("writing phase_step_rad_int = %d to d_map_base 3\n", phase_step_rad_int); | ||||
|     d_map_base[3] = phase_step_rad_int; | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_acquisition::read_acquisition_results(uint32_t *max_index, | ||||
|     float *max_magnitude, uint32_t *initial_sample, float *power_sum) | ||||
|     float *max_magnitude, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index) | ||||
| { | ||||
|     uint64_t initial_sample_tmp = 0; | ||||
|  | ||||
|     uint32_t readval = 0; | ||||
|     uint64_t readval_long = 0; | ||||
|     uint64_t readval_long_shifted = 0; | ||||
|     readval = d_map_base[1]; | ||||
|     *initial_sample = readval; | ||||
|     readval = d_map_base[2]; | ||||
|     initial_sample_tmp = readval; | ||||
|     readval_long = d_map_base[2]; | ||||
|     readval_long_shifted = readval_long << 32;                       // 2^32 | ||||
|     initial_sample_tmp = initial_sample_tmp + readval_long_shifted;  // 2^32 | ||||
|     //printf("----------------------------------------------------------------> acq initial sample TOTAL = %llu\n", initial_sample_tmp); | ||||
|     *initial_sample = initial_sample_tmp; | ||||
|     readval = d_map_base[6]; | ||||
|     *max_magnitude = static_cast<float>(readval); | ||||
|     //printf("read max_magnitude dmap 2 = %d\n", readval); | ||||
|     readval = d_map_base[4]; | ||||
|     *power_sum = static_cast<float>(readval); | ||||
|     //printf("read power sum dmap 4 = %d\n", readval); | ||||
|     readval = d_map_base[5];  // read doppler index | ||||
|     *doppler_index = readval; | ||||
|     //printf("read doppler_index dmap 5 = %d\n", readval); | ||||
|     readval = d_map_base[3]; | ||||
|     *max_index = readval; | ||||
|     //printf("read max index dmap 3 = %d\n", readval); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -260,5 +419,5 @@ void fpga_acquisition::close_device() | ||||
|  | ||||
| void fpga_acquisition::reset_acquisition(void) | ||||
| { | ||||
|     d_map_base[6] = RESET_ACQUISITION;  // writing a 2 to d_map_base[6] resets the multicorrelator | ||||
|     d_map_base[8] = RESET_ACQUISITION;  // writing a 2 to d_map_base[8] resets the multicorrelator | ||||
| } | ||||
|   | ||||
| @@ -59,10 +59,12 @@ public: | ||||
|     bool init(); | ||||
|     bool set_local_code(uint32_t PRN); | ||||
|     bool free(); | ||||
|     void set_doppler_sweep(uint32_t num_sweeps); | ||||
|     void set_doppler_sweep_debug(uint32_t num_sweeps, uint32_t doppler_index); | ||||
|     void run_acquisition(void); | ||||
|     void set_phase_step(uint32_t doppler_index); | ||||
|     void read_acquisition_results(uint32_t *max_index, float *max_magnitude, | ||||
|         uint32_t *initial_sample, float *power_sum); | ||||
|         uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index); | ||||
|     void block_samples(); | ||||
|     void unblock_samples(); | ||||
|  | ||||
|   | ||||
| @@ -22,7 +22,7 @@ if(ENABLE_CUDA) | ||||
| endif(ENABLE_CUDA) | ||||
|  | ||||
| if(ENABLE_FPGA) | ||||
|      SET(OPT_TRACKING_ADAPTERS ${OPT_TRACKING_ADAPTERS} gps_l1_ca_dll_pll_tracking_fpga.cc) | ||||
|      SET(OPT_TRACKING_ADAPTERS ${OPT_TRACKING_ADAPTERS} gps_l1_ca_dll_pll_tracking_fpga.cc gps_l2_m_dll_pll_tracking_fpga.cc galileo_e1_dll_pll_veml_tracking_fpga.cc galileo_e5a_dll_pll_tracking_fpga.cc gps_l5_dll_pll_tracking_fpga.cc) | ||||
| endif(ENABLE_FPGA) | ||||
|  | ||||
| set(TRACKING_ADAPTER_SOURCES | ||||
|   | ||||
| @@ -0,0 +1,268 @@ | ||||
| /*! | ||||
|  * \file galileo_e1_dll_pll_veml_tracking.cc | ||||
|  * \brief  Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block | ||||
|  *   to a TrackingInterface for Galileo E1 signals | ||||
|  * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  * | ||||
|  * Code DLL + carrier PLL according to the algorithms described in: | ||||
|  * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, | ||||
|  * A Software-Defined GPS and Galileo Receiver. A Single-Frequency | ||||
|  * Approach, Birkhauser, 2007 | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "galileo_e1_dll_pll_veml_tracking_fpga.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "Galileo_E1.h" | ||||
| #include "galileo_e1_signal_processing.h" | ||||
| #include "gnss_sdr_flags.h" | ||||
| #include "display.h" | ||||
| #include <glog/logging.h> | ||||
|  | ||||
| //#define NUM_PRNs_GALILEO_E1 50 | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga( | ||||
|     ConfigurationInterface* configuration, std::string role, | ||||
|     unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) | ||||
| { | ||||
|     //dllpllconf_t trk_param; | ||||
| 	Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); | ||||
|     DLOG(INFO) << "role " << role; | ||||
|     //################# CONFIGURATION PARAMETERS ######################## | ||||
|     std::string default_item_type = "gr_complex"; | ||||
|     std::string item_type = configuration->property(role + ".item_type", default_item_type); | ||||
|     int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||
|     int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|     trk_param_fpga.fs_in = fs_in; | ||||
|     bool dump = configuration->property(role + ".dump", false); | ||||
|     trk_param_fpga.dump = dump; | ||||
|     float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 5.0); | ||||
|     if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz); | ||||
|     trk_param_fpga.pll_bw_hz = pll_bw_hz; | ||||
|     float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 0.5); | ||||
|     if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz); | ||||
|     trk_param_fpga.dll_bw_hz = dll_bw_hz; | ||||
|     float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 2.0); | ||||
|     trk_param_fpga.pll_bw_narrow_hz = pll_bw_narrow_hz; | ||||
|     float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 0.25); | ||||
|     trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz; | ||||
|     int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); | ||||
|     float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.15); | ||||
|     trk_param_fpga.early_late_space_chips = early_late_space_chips; | ||||
|     float very_early_late_space_chips = configuration->property(role + ".very_early_late_space_chips", 0.6); | ||||
|     trk_param_fpga.very_early_late_space_chips = very_early_late_space_chips; | ||||
|     float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15); | ||||
|     trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips; | ||||
|     float very_early_late_space_narrow_chips = configuration->property(role + ".very_early_late_space_narrow_chips", 0.6); | ||||
|     trk_param_fpga.very_early_late_space_narrow_chips = very_early_late_space_narrow_chips; | ||||
|     bool track_pilot = configuration->property(role + ".track_pilot", false); | ||||
|     if (extend_correlation_symbols < 1) | ||||
|         { | ||||
|             extend_correlation_symbols = 1; | ||||
|             std::cout << TEXT_RED << "WARNING: Galileo E1. extend_correlation_symbols must be bigger than 0. Coherent integration has been set to 1 symbol (4 ms)" << TEXT_RESET << std::endl; | ||||
|         } | ||||
|     else if (!track_pilot and extend_correlation_symbols > 1) | ||||
|         { | ||||
|             extend_correlation_symbols = 1; | ||||
|             std::cout << TEXT_RED << "WARNING: Galileo E1. Extended coherent integration is not allowed when tracking the data component. Coherent integration has been set to 4 ms (1 symbol)" << TEXT_RESET << std::endl; | ||||
|         } | ||||
|     if ((extend_correlation_symbols > 1) and (pll_bw_narrow_hz > pll_bw_hz or dll_bw_narrow_hz > dll_bw_hz)) | ||||
|         { | ||||
|             std::cout << TEXT_RED << "WARNING: Galileo E1. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << std::endl; | ||||
|         } | ||||
|     trk_param_fpga.track_pilot = track_pilot; | ||||
|     d_track_pilot = track_pilot; | ||||
|     trk_param_fpga.extend_correlation_symbols = extend_correlation_symbols; | ||||
|     std::string default_dump_filename = "./track_ch"; | ||||
|     std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); | ||||
|     trk_param_fpga.dump_filename = dump_filename; | ||||
|     int vector_length = std::round(fs_in / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)); | ||||
|     trk_param_fpga.vector_length = vector_length; | ||||
|     trk_param_fpga.system = 'E'; | ||||
|     char sig_[3] = "1B"; | ||||
|     std::memcpy(trk_param_fpga.signal, sig_, 3); | ||||
|     int cn0_samples = configuration->property(role + ".cn0_samples", 20); | ||||
|     if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; | ||||
|     trk_param_fpga.cn0_samples = cn0_samples; | ||||
|     int cn0_min = configuration->property(role + ".cn0_min", 25); | ||||
|     if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; | ||||
|     trk_param_fpga.cn0_min = cn0_min; | ||||
|     int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); | ||||
|     if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; | ||||
|     trk_param_fpga.max_lock_fail = max_lock_fail; | ||||
|     double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); | ||||
|     if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; | ||||
|     trk_param_fpga.carrier_lock_th = carrier_lock_th; | ||||
|  | ||||
|     // FPGA configuration parameters | ||||
|     std::string default_device_name = "/dev/uio"; | ||||
|     std::string device_name = configuration->property(role + ".devicename", default_device_name); | ||||
|     trk_param_fpga.device_name = device_name; | ||||
|     unsigned int device_base = configuration->property(role + ".device_base", 1); | ||||
|     trk_param_fpga.device_base = device_base; | ||||
|     //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 1); | ||||
|     trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> 5 correlators | ||||
|  | ||||
|     //################# PRE-COMPUTE ALL THE CODES ################# | ||||
|     unsigned int code_samples_per_chip = 2; | ||||
|     d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* code_samples_per_chip * Galileo_E1_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|     float * ca_codes_f; | ||||
|     float * data_codes_f; | ||||
|  | ||||
|     if (trk_param_fpga.track_pilot) | ||||
|         { | ||||
|             d_data_codes = static_cast<int *>(volk_gnsssdr_malloc((static_cast<unsigned int>(Galileo_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * Galileo_E1_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|         } | ||||
|     ca_codes_f = static_cast<float*>(volk_gnsssdr_malloc(static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment())); | ||||
|  | ||||
|     if (trk_param_fpga.track_pilot) | ||||
|         { | ||||
|             data_codes_f = static_cast<float *>(volk_gnsssdr_malloc((static_cast<unsigned int>(Galileo_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment())); | ||||
|         } | ||||
|  | ||||
|     //printf("pppppppp trk_param_fpga.track_pilot = %d\n", trk_param_fpga.track_pilot); | ||||
|  | ||||
|     //int kk; | ||||
|  | ||||
|     for (unsigned int PRN = 1; PRN <= Galileo_E1_NUMBER_OF_CODES; PRN++) | ||||
|         { | ||||
|             char data_signal[3] = "1B"; | ||||
|             if (trk_param_fpga.track_pilot) | ||||
|                 { | ||||
|                     //printf("yes tracking pilot !!!!!!!!!!!!!!!\n"); | ||||
|                     char pilot_signal[3] = "1C"; | ||||
|                     galileo_e1_code_gen_sinboc11_float(ca_codes_f, pilot_signal, PRN); | ||||
|                     galileo_e1_code_gen_sinboc11_float(data_codes_f, data_signal, PRN); | ||||
|  | ||||
|                     for (unsigned int s = 0; s < 2*Galileo_E1_B_CODE_LENGTH_CHIPS; s++) | ||||
|                         { | ||||
|                             d_ca_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s] = static_cast<int>(ca_codes_f[s]); | ||||
|                             d_data_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s] = static_cast<int>(data_codes_f[s]); | ||||
|                             //printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); | ||||
|  | ||||
|                         } | ||||
|                     //printf("\n next \n"); | ||||
|                     //scanf ("%d",&kk); | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     //printf("no tracking pilot\n"); | ||||
|                     galileo_e1_code_gen_sinboc11_float(ca_codes_f, data_signal, PRN); | ||||
|  | ||||
|                     for (unsigned int s = 0; s < 2*Galileo_E1_B_CODE_LENGTH_CHIPS; s++) | ||||
|                         { | ||||
|                             d_ca_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s] = static_cast<int>(ca_codes_f[s]); | ||||
|                             //printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); | ||||
|                         } | ||||
|                     //printf("\n next \n"); | ||||
|                     //scanf ("%d",&kk); | ||||
|                 } | ||||
|  | ||||
|         } | ||||
|  | ||||
|     delete[] ca_codes_f; | ||||
|     if (trk_param_fpga.track_pilot) | ||||
|         { | ||||
|             delete[] data_codes_f; | ||||
|         } | ||||
|     trk_param_fpga.ca_codes = d_ca_codes; | ||||
|     trk_param_fpga.data_codes = d_data_codes; | ||||
|     trk_param_fpga.code_length_chips = Galileo_E1_B_CODE_LENGTH_CHIPS; | ||||
|     trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip | ||||
|     //################# MAKE TRACKING GNURadio object ################### | ||||
|     tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); | ||||
|     channel_ = 0; | ||||
|     DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; | ||||
| } | ||||
|  | ||||
|  | ||||
| GalileoE1DllPllVemlTrackingFpga::~GalileoE1DllPllVemlTrackingFpga() | ||||
| { | ||||
|     delete[] d_ca_codes; | ||||
|     if (d_track_pilot) | ||||
|         { | ||||
|             delete[] d_data_codes; | ||||
|  | ||||
|         } | ||||
| } | ||||
|  | ||||
| void GalileoE1DllPllVemlTrackingFpga::start_tracking() | ||||
| { | ||||
|     //tracking_->start_tracking(); | ||||
|     tracking_fpga_sc->start_tracking(); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Set tracking channel unique ID | ||||
|  */ | ||||
| void GalileoE1DllPllVemlTrackingFpga::set_channel(unsigned int channel) | ||||
| { | ||||
|     channel_ = channel; | ||||
|     //tracking_->set_channel(channel); | ||||
|     tracking_fpga_sc->set_channel(channel); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1DllPllVemlTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) | ||||
| { | ||||
|     //tracking_->set_gnss_synchro(p_gnss_synchro); | ||||
|     tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1DllPllVemlTrackingFpga::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     if (top_block) | ||||
|         { /* top_block is not null */ | ||||
|         }; | ||||
|     //nothing to connect, now the tracking uses gr_sync_decimator | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE1DllPllVemlTrackingFpga::disconnect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     if (top_block) | ||||
|         { /* top_block is not null */ | ||||
|         }; | ||||
|     //nothing to disconnect, now the tracking uses gr_sync_decimator | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GalileoE1DllPllVemlTrackingFpga::get_left_block() | ||||
| { | ||||
|     //return tracking_; | ||||
|     return tracking_fpga_sc; | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GalileoE1DllPllVemlTrackingFpga::get_right_block() | ||||
| { | ||||
|     //return tracking_; | ||||
|     return tracking_fpga_sc; | ||||
| } | ||||
| @@ -0,0 +1,111 @@ | ||||
| /*! | ||||
|  * \file galileo_e1_dll_pll_veml_tracking.h | ||||
|  * \brief  Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block | ||||
|  *   to a TrackingInterface for Galileo E1 signals | ||||
|  * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  * | ||||
|  * Code DLL + carrier PLL according to the algorithms described in: | ||||
|  * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, | ||||
|  * A Software-Defined GPS and Galileo Receiver. A Single-Frequency | ||||
|  * Approach, Birkhauser, 2007 | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_FPGA_H_ | ||||
| #define GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_FPGA_H_ | ||||
|  | ||||
| #include "tracking_interface.h" | ||||
| #include "dll_pll_veml_tracking_fpga.h" | ||||
| #include <string> | ||||
|  | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| /*! | ||||
|  * \brief This class Adapts a DLL+PLL VEML (Very Early Minus Late) tracking | ||||
|  * loop block to a TrackingInterface for Galileo E1 signals | ||||
|  */ | ||||
| class GalileoE1DllPllVemlTrackingFpga : public TrackingInterface | ||||
| { | ||||
| public: | ||||
|     GalileoE1DllPllVemlTrackingFpga(ConfigurationInterface* configuration, | ||||
|         std::string role, | ||||
|         unsigned int in_streams, | ||||
|         unsigned int out_streams); | ||||
|  | ||||
|     virtual ~GalileoE1DllPllVemlTrackingFpga(); | ||||
|  | ||||
|     inline std::string role() override | ||||
|     { | ||||
|         return role_; | ||||
|     } | ||||
|  | ||||
|     //! Returns "Galileo_E1_DLL_PLL_VEML_Tracking" | ||||
|     inline std::string implementation() override | ||||
|     { | ||||
|         return "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"; | ||||
|     } | ||||
|  | ||||
|     inline size_t item_size() override | ||||
|     { | ||||
|         return item_size_; | ||||
|     } | ||||
|  | ||||
|     void connect(gr::top_block_sptr top_block) override; | ||||
|     void disconnect(gr::top_block_sptr top_block) override; | ||||
|     gr::basic_block_sptr get_left_block() override; | ||||
|     gr::basic_block_sptr get_right_block() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set tracking channel unique ID | ||||
|      */ | ||||
|     void set_channel(unsigned int channel) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition/tracking common Gnss_Synchro object pointer | ||||
|      * to efficiently exchange synchronization data between acquisition and | ||||
|      *  tracking blocks | ||||
|      */ | ||||
|     void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; | ||||
|  | ||||
|     void start_tracking() override; | ||||
|  | ||||
| private: | ||||
|     //dll_pll_veml_tracking_sptr tracking_; | ||||
|     dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; | ||||
|     size_t item_size_; | ||||
|     unsigned int channel_; | ||||
|     std::string role_; | ||||
|     unsigned int in_streams_; | ||||
|     unsigned int out_streams_; | ||||
|     int* d_ca_codes; | ||||
|     int* d_data_codes; | ||||
|     bool d_track_pilot; | ||||
|  | ||||
| }; | ||||
|  | ||||
|  | ||||
| #endif  // GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_FPGA_H_ | ||||
| @@ -0,0 +1,293 @@ | ||||
| /*! | ||||
|  * \file galileo_e5a_dll_pll_tracking.cc | ||||
|  * \brief Adapts a code DLL + carrier PLL | ||||
|  *  tracking block to a TrackingInterface for Galileo E5a signals | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  Galileo E5a data and pilot Signals | ||||
|  * \author Marc Sales, 2014. marcsales92(at)gmail.com | ||||
|  * \based on work from: | ||||
|  *          <ul> | ||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  *          </ul> | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "galileo_e5a_dll_pll_tracking_fpga.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "Galileo_E5a.h" | ||||
| #include "galileo_e5_signal_processing.h" | ||||
| #include "gnss_sdr_flags.h" | ||||
| #include "display.h" | ||||
| #include <glog/logging.h> | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( | ||||
|     ConfigurationInterface* configuration, std::string role, | ||||
|     unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) | ||||
| { | ||||
| 	//printf("creating the E5A tracking"); | ||||
|  | ||||
|  | ||||
| 	Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); | ||||
|     DLOG(INFO) << "role " << role; | ||||
|     //################# CONFIGURATION PARAMETERS ######################## | ||||
|     std::string default_item_type = "gr_complex"; | ||||
|     std::string item_type = configuration->property(role + ".item_type", default_item_type); | ||||
|     int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 12000000); | ||||
|     int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|     trk_param_fpga.fs_in = fs_in; | ||||
|     bool dump = configuration->property(role + ".dump", false); | ||||
|     trk_param_fpga.dump = dump; | ||||
|     float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 20.0); | ||||
|     if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz); | ||||
|     trk_param_fpga.pll_bw_hz = pll_bw_hz; | ||||
|     float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 20.0); | ||||
|     if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz); | ||||
|     trk_param_fpga.dll_bw_hz = dll_bw_hz; | ||||
|     float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 5.0); | ||||
|     trk_param_fpga.pll_bw_narrow_hz = pll_bw_narrow_hz; | ||||
|     float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 2.0); | ||||
|     trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz; | ||||
|     float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); | ||||
|     trk_param_fpga.early_late_space_chips = early_late_space_chips; | ||||
|     std::string default_dump_filename = "./track_ch"; | ||||
|     std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); | ||||
|     trk_param_fpga.dump_filename = dump_filename; | ||||
|     int vector_length = std::round(fs_in / (Galileo_E5a_CODE_CHIP_RATE_HZ / Galileo_E5a_CODE_LENGTH_CHIPS)); | ||||
|     trk_param_fpga.vector_length = vector_length; | ||||
|     int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); | ||||
|     float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15); | ||||
|     trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips; | ||||
|     bool track_pilot = configuration->property(role + ".track_pilot", false); | ||||
|     d_track_pilot = track_pilot; | ||||
|     if (extend_correlation_symbols < 1) | ||||
|         { | ||||
|             extend_correlation_symbols = 1; | ||||
|             std::cout << TEXT_RED << "WARNING: Galileo E5a. extend_correlation_symbols must be bigger than 0. Coherent integration has been set to 1 symbol (1 ms)" << TEXT_RESET << std::endl; | ||||
|         } | ||||
|     else if (!track_pilot and extend_correlation_symbols > Galileo_E5a_I_SECONDARY_CODE_LENGTH) | ||||
|         { | ||||
|             extend_correlation_symbols = Galileo_E5a_I_SECONDARY_CODE_LENGTH; | ||||
|             std::cout << TEXT_RED << "WARNING: Galileo E5a. extend_correlation_symbols must be lower than 21 when tracking the data component. Coherent integration has been set to 20 symbols (20 ms)" << TEXT_RESET << std::endl; | ||||
|         } | ||||
|     if ((extend_correlation_symbols > 1) and (pll_bw_narrow_hz > pll_bw_hz or dll_bw_narrow_hz > dll_bw_hz)) | ||||
|         { | ||||
|             std::cout << TEXT_RED << "WARNING: Galileo E5a. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << std::endl; | ||||
|         } | ||||
|     trk_param_fpga.extend_correlation_symbols = extend_correlation_symbols; | ||||
|     trk_param_fpga.track_pilot = track_pilot; | ||||
|     trk_param_fpga.very_early_late_space_chips = 0.0; | ||||
|     trk_param_fpga.very_early_late_space_narrow_chips = 0.0; | ||||
|     trk_param_fpga.system = 'E'; | ||||
|     char sig_[3] = "5X"; | ||||
|     std::memcpy(trk_param_fpga.signal, sig_, 3); | ||||
|     int cn0_samples = configuration->property(role + ".cn0_samples", 20); | ||||
|     if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; | ||||
|     trk_param_fpga.cn0_samples = cn0_samples; | ||||
|     int cn0_min = configuration->property(role + ".cn0_min", 25); | ||||
|     if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; | ||||
|     trk_param_fpga.cn0_min = cn0_min; | ||||
|     int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); | ||||
|     if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; | ||||
|     trk_param_fpga.max_lock_fail = max_lock_fail; | ||||
|     double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); | ||||
|     if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; | ||||
|     trk_param_fpga.carrier_lock_th = carrier_lock_th; | ||||
|  | ||||
|     // FPGA configuration parameters | ||||
|     std::string default_device_name = "/dev/uio"; | ||||
|     std::string device_name = configuration->property(role + ".devicename", default_device_name); | ||||
|     trk_param_fpga.device_name = device_name; | ||||
|     unsigned int device_base = configuration->property(role + ".device_base", 1); | ||||
|     trk_param_fpga.device_base = device_base; | ||||
|     //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 1); | ||||
|     trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> up to 5+1 correlators | ||||
|  | ||||
|     //################# PRE-COMPUTE ALL THE CODES ################# | ||||
|     unsigned int code_samples_per_chip = 1; | ||||
|     unsigned int code_length_chips = static_cast<unsigned int>(Galileo_E5a_CODE_LENGTH_CHIPS); | ||||
|  | ||||
|     gr_complex *aux_code = static_cast<gr_complex *>(volk_gnsssdr_malloc(sizeof(gr_complex) * code_length_chips * code_samples_per_chip, volk_gnsssdr_get_alignment())); | ||||
|  | ||||
|     float *tracking_code; | ||||
|     float *data_code; | ||||
|  | ||||
|     if (trk_param_fpga.track_pilot) | ||||
|         { | ||||
|             data_code = static_cast<float *>(volk_gnsssdr_malloc(code_samples_per_chip * code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); | ||||
|         } | ||||
|     tracking_code = static_cast<float *>(volk_gnsssdr_malloc(code_samples_per_chip * code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); | ||||
|  | ||||
|     d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(code_length_chips)* code_samples_per_chip * Galileo_E5a_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|  | ||||
|     if (trk_param_fpga.track_pilot) | ||||
|         { | ||||
|             d_data_codes = static_cast<int *>(volk_gnsssdr_malloc((static_cast<unsigned int>(code_length_chips)) * code_samples_per_chip * Galileo_E5a_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|         } | ||||
|  | ||||
|  | ||||
|     for (unsigned int PRN = 1; PRN <= Galileo_E5a_NUMBER_OF_CODES; PRN++) | ||||
|         { | ||||
|  | ||||
|  | ||||
|  | ||||
|         //galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast<char *>(trk_param_fpga.signal.c_str())); | ||||
|         galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast<char *>(sig_)); | ||||
|         if (trk_param_fpga.track_pilot) | ||||
|             { | ||||
|                 //d_secondary_code_string = const_cast<std::string *>(&Galileo_E5a_Q_SECONDARY_CODE[PRN - 1]); | ||||
|                 for (unsigned int i = 0; i < code_length_chips; i++) | ||||
|                     { | ||||
|                         tracking_code[i] = aux_code[i].imag(); | ||||
|                         data_code[i] = aux_code[i].real(); | ||||
|                     } | ||||
|                 for (unsigned int s = 0; s < code_length_chips; s++) | ||||
|                     { | ||||
|                         d_ca_codes[static_cast<int>(code_length_chips) * (PRN - 1) + s] = static_cast<int>(tracking_code[s]); | ||||
|                         d_data_codes[static_cast<int>(code_length_chips) * (PRN - 1) + s] = static_cast<int>(data_code[s]); | ||||
|                         //printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); | ||||
|  | ||||
|                     } | ||||
|  | ||||
|             } | ||||
|         else | ||||
|             { | ||||
|                 for (unsigned int i = 0; i < code_length_chips; i++) | ||||
|                     { | ||||
|                         tracking_code[i] = aux_code[i].real(); | ||||
|                     } | ||||
|  | ||||
|                 for (unsigned int s = 0; s < code_length_chips; s++) | ||||
|                     { | ||||
|                         d_ca_codes[static_cast<int>(code_length_chips)* (PRN - 1) + s] = static_cast<int>(tracking_code[s]); | ||||
|                         //printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); | ||||
|                     } | ||||
|  | ||||
|             } | ||||
|  | ||||
|  | ||||
|         } | ||||
|  | ||||
|     volk_gnsssdr_free(aux_code); | ||||
|     volk_gnsssdr_free(tracking_code); | ||||
|     if (trk_param_fpga.track_pilot) | ||||
|         { | ||||
|             volk_gnsssdr_free(data_code); | ||||
|         } | ||||
|     trk_param_fpga.ca_codes = d_ca_codes; | ||||
|     trk_param_fpga.data_codes = d_data_codes; | ||||
|     trk_param_fpga.code_length_chips = code_length_chips; | ||||
|     trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip | ||||
|     //################# MAKE TRACKING GNURadio object ################### | ||||
|     tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); | ||||
| //    if (item_type.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            item_size_ = sizeof(gr_complex); | ||||
| //            tracking_ = dll_pll_veml_make_tracking(trk_param_fpga); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            item_size_ = sizeof(gr_complex); | ||||
| //            LOG(WARNING) << item_type << " unknown tracking item type."; | ||||
| //        } | ||||
|     channel_ = 0; | ||||
|  | ||||
|     //DLOG(INFO) << "tracking(" << tracking_->unique_id() << ")"; | ||||
|     DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| GalileoE5aDllPllTrackingFpga::~GalileoE5aDllPllTrackingFpga() | ||||
| { | ||||
|     delete[] d_ca_codes; | ||||
|     if (d_track_pilot) | ||||
|         { | ||||
|             delete[] d_data_codes; | ||||
|  | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aDllPllTrackingFpga::start_tracking() | ||||
| { | ||||
|     //tracking_->start_tracking(); | ||||
|     tracking_fpga_sc->start_tracking(); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Set tracking channel unique ID | ||||
|  */ | ||||
| void GalileoE5aDllPllTrackingFpga::set_channel(unsigned int channel) | ||||
| { | ||||
| 	//printf("blabla channel = %d\n", channel); | ||||
|     channel_ = channel; | ||||
|     //tracking_->set_channel(channel); | ||||
|     tracking_fpga_sc->set_channel(channel); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aDllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) | ||||
| { | ||||
|     //tracking_->set_gnss_synchro(p_gnss_synchro); | ||||
|     tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GalileoE5aDllPllTrackingFpga::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 GalileoE5aDllPllTrackingFpga::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 GalileoE5aDllPllTrackingFpga::get_left_block() | ||||
| { | ||||
|     //return tracking_; | ||||
|     return tracking_fpga_sc; | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GalileoE5aDllPllTrackingFpga::get_right_block() | ||||
| { | ||||
|     //return tracking_; | ||||
|     return tracking_fpga_sc; | ||||
| } | ||||
| @@ -0,0 +1,110 @@ | ||||
| /*! | ||||
|  * \file galileo_e5a_dll_pll_tracking.h | ||||
|  * \brief Adapts a code DLL + carrier PLL | ||||
|  *  tracking block to a TrackingInterface for Galileo E5a signals | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  Galileo E5a data and pilot Signals | ||||
|  * \author Marc Sales, 2014. marcsales92(at)gmail.com | ||||
|  * \based on work from: | ||||
|  *          <ul> | ||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  *          </ul> | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_GALILEO_E5A_DLL_PLL_TRACKING_FPGA_H_ | ||||
| #define GNSS_SDR_GALILEO_E5A_DLL_PLL_TRACKING_FPGA_H_ | ||||
|  | ||||
| #include "tracking_interface.h" | ||||
| #include "dll_pll_veml_tracking_fpga.h" | ||||
| #include <string> | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| /*! | ||||
|  * \brief This class implements a code DLL + carrier PLL tracking loop | ||||
|  */ | ||||
| class GalileoE5aDllPllTrackingFpga : public TrackingInterface | ||||
| { | ||||
| public: | ||||
|     GalileoE5aDllPllTrackingFpga(ConfigurationInterface* configuration, | ||||
|         std::string role, | ||||
|         unsigned int in_streams, | ||||
|         unsigned int out_streams); | ||||
|  | ||||
|     virtual ~GalileoE5aDllPllTrackingFpga(); | ||||
|  | ||||
|     inline std::string role() override | ||||
|     { | ||||
|         return role_; | ||||
|     } | ||||
|  | ||||
|     //! Returns "Galileo_E5a_DLL_PLL_Tracking" | ||||
|     inline std::string implementation() override | ||||
|     { | ||||
|         return "Galileo_E5a_DLL_PLL_Tracking"; | ||||
|     } | ||||
|  | ||||
|     inline size_t item_size() override | ||||
|     { | ||||
|         return item_size_; | ||||
|     } | ||||
|  | ||||
|     void connect(gr::top_block_sptr top_block) override; | ||||
|     void disconnect(gr::top_block_sptr top_block) override; | ||||
|     gr::basic_block_sptr get_left_block() override; | ||||
|     gr::basic_block_sptr get_right_block() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set tracking channel unique ID | ||||
|      */ | ||||
|     void set_channel(unsigned int channel) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition/tracking common Gnss_Synchro object pointer | ||||
|      * to efficiently exchange synchronization data between acquisition and tracking blocks | ||||
|      */ | ||||
|     void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; | ||||
|  | ||||
|     void start_tracking() override; | ||||
|  | ||||
| private: | ||||
|     dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; | ||||
|     size_t item_size_; | ||||
|     unsigned int channel_; | ||||
|     std::string role_; | ||||
|     unsigned int in_streams_; | ||||
|     unsigned int out_streams_; | ||||
|  | ||||
|  | ||||
|     int* d_ca_codes; | ||||
|     int* d_data_codes; | ||||
|     bool d_track_pilot; | ||||
|  | ||||
| }; | ||||
|  | ||||
| #endif /* GNSS_SDR_GALILEO_E5A_DLL_PLL_TRACKING_FPGA_H_ */ | ||||
| @@ -1,5 +1,5 @@ | ||||
| /*! | ||||
|  * \file gps_l1_ca_dll_pll_tracking.cc | ||||
|  * \file gps_l1_ca_dll_pll_tracking_fpga.cc | ||||
|  * \brief Implementation of an adapter of a DLL+PLL tracking loop block | ||||
|  * for GPS L1 C/A to a TrackingInterface that uses the FPGA | ||||
|  * \author Marc Majoral, 2018, mmajoral(at)cttc.es | ||||
| @@ -13,7 +13,7 @@ | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (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,19 +31,18 @@ | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include <glog/logging.h> | ||||
| #include "gps_sdr_signal_processing.h" | ||||
| #include "gps_l1_ca_dll_pll_tracking_fpga.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "display.h" | ||||
| #include "gnss_sdr_flags.h" | ||||
| #include "GPS_L1_CA.h" | ||||
| #include "gps_sdr_signal_processing.h" | ||||
| #include <glog/logging.h> | ||||
|  | ||||
| #include "gnss_sdr_flags.h" | ||||
| #include "display.h" | ||||
|  | ||||
| #define NUM_PRNs 32 | ||||
|  | ||||
| @@ -51,12 +50,15 @@ 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) | ||||
|         unsigned int in_streams, unsigned int out_streams) : | ||||
|                 role_(role), in_streams_(in_streams), out_streams_(out_streams) | ||||
| { | ||||
|     dllpllconf_fpga_t trk_param_fpga; | ||||
| 	Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); | ||||
|     DLOG(INFO) << "role " << role; | ||||
|      | ||||
|     //################# CONFIGURATION PARAMETERS ######################## | ||||
|     //std::string default_item_type = "gr_complex"; | ||||
|     //std::string item_type = configuration->property(role + ".item_type", default_item_type); | ||||
|     int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||
|     int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|     trk_param_fpga.fs_in = fs_in; | ||||
| @@ -127,43 +129,36 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga( | ||||
|     trk_param_fpga.device_name = device_name; | ||||
|     unsigned int device_base = configuration->property(role + ".device_base", 1); | ||||
|     trk_param_fpga.device_base = device_base; | ||||
|     //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0); | ||||
|     trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators | ||||
|  | ||||
|     //################# PRE-COMPUTE ALL THE CODES ################# | ||||
|     d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS * NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|     d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS*NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|     for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) | ||||
|     { | ||||
|         gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0); | ||||
|     } | ||||
|     trk_param_fpga.ca_codes = d_ca_codes; | ||||
|     trk_param_fpga.code_length = GPS_L1_CA_CODE_LENGTH_CHIPS; | ||||
|     trk_param_fpga.code_length_chips = GPS_L1_CA_CODE_LENGTH_CHIPS; | ||||
|     trk_param_fpga.code_samples_per_chip = 1; // 1 sample per chip | ||||
|  | ||||
|     //################# MAKE TRACKING GNURadio object ################### | ||||
|     tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); | ||||
|     channel_ = 0; | ||||
|     DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; | ||||
|     if (in_streams_ > 1) | ||||
|         { | ||||
|             LOG(ERROR) << "This implementation only supports one input stream"; | ||||
|         } | ||||
|     if (out_streams_ > 1) | ||||
|         { | ||||
|             LOG(ERROR) << "This implementation only supports one output stream"; | ||||
|         } | ||||
| } | ||||
|      | ||||
| } | ||||
|  | ||||
| GpsL1CaDllPllTrackingFpga::~GpsL1CaDllPllTrackingFpga() | ||||
| { | ||||
|     delete[] d_ca_codes; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL1CaDllPllTrackingFpga::start_tracking() | ||||
| { | ||||
|     tracking_fpga_sc->start_tracking(); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Set tracking channel unique ID | ||||
|  */ | ||||
| @@ -173,27 +168,21 @@ void GpsL1CaDllPllTrackingFpga::set_channel(unsigned int 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 */ | ||||
|         }; | ||||
|     if(top_block) { /* top_block is not null */}; | ||||
|     //nothing to connect | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL1CaDllPllTrackingFpga::disconnect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     if (top_block) | ||||
|         { /* top_block is not null */ | ||||
|         }; | ||||
|     if(top_block) { /* top_block is not null */}; | ||||
|     //nothing to disconnect | ||||
| } | ||||
|  | ||||
| @@ -208,3 +197,5 @@ gr::basic_block_sptr GpsL1CaDllPllTrackingFpga::get_right_block() | ||||
| { | ||||
|     return tracking_fpga_sc; | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /*! | ||||
|  * \file gps_l1_ca_dll_pll_tracking.h | ||||
|  * \file gps_l1_ca_dll_pll_tracking_fpga.h | ||||
|  * \brief  Interface of an adapter of a DLL+PLL tracking loop block | ||||
|  * for GPS L1 C/A to a TrackingInterface that uses the FPGA | ||||
|  * \author Marc Majoral, 2018. mmajoral(at)cttc.es | ||||
| @@ -13,7 +13,7 @@ | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (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,7 +31,7 @@ | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
| @@ -39,9 +39,10 @@ | ||||
| #ifndef GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_H_ | ||||
| #define GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_H_ | ||||
|  | ||||
| #include <string> | ||||
| #include "tracking_interface.h" | ||||
| #include "dll_pll_veml_tracking_fpga.h" | ||||
| #include <string> | ||||
|  | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| @@ -92,6 +93,8 @@ public: | ||||
|  | ||||
|     void start_tracking() override; | ||||
|  | ||||
| 	//void reset(void); | ||||
| 	 | ||||
| private: | ||||
| 	dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; | ||||
|     size_t item_size_; | ||||
|   | ||||
| @@ -0,0 +1,223 @@ | ||||
| /*! | ||||
|  * \file gps_l2_m_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 Javier Arribas, 2015. 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 <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include "gps_l2_m_dll_pll_tracking_fpga.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "GPS_L2C.h" | ||||
| #include "gps_l2c_signal.h" | ||||
| #include "gnss_sdr_flags.h" | ||||
| #include "display.h" | ||||
| #include <glog/logging.h> | ||||
|  | ||||
| #define NUM_PRNs 32 | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| GpsL2MDllPllTrackingFpga::GpsL2MDllPllTrackingFpga( | ||||
|     ConfigurationInterface* configuration, std::string role, | ||||
|     unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) | ||||
| { | ||||
|     //dllpllconf_t trk_param; | ||||
| 	Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); | ||||
|     DLOG(INFO) << "role " << role; | ||||
|     //################# CONFIGURATION PARAMETERS ######################## | ||||
|     //std::string default_item_type = "gr_complex"; | ||||
|     //std::string item_type = configuration->property(role + ".item_type", default_item_type); | ||||
|     int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||
|     int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|     trk_param_fpga.fs_in = fs_in; | ||||
|     bool dump = configuration->property(role + ".dump", false); | ||||
|     trk_param_fpga.dump = dump; | ||||
|     float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 2.0); | ||||
|     if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz); | ||||
|     trk_param_fpga.pll_bw_hz = pll_bw_hz; | ||||
|     float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 0.75); | ||||
|     if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz); | ||||
|     trk_param_fpga.dll_bw_hz = dll_bw_hz; | ||||
|     float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); | ||||
|     trk_param_fpga.early_late_space_chips = early_late_space_chips; | ||||
|     trk_param_fpga.early_late_space_narrow_chips = 0.0; | ||||
|     std::string default_dump_filename = "./track_ch"; | ||||
|     std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); | ||||
|     trk_param_fpga.dump_filename = dump_filename; | ||||
|     int vector_length = std::round(static_cast<double>(fs_in) / (static_cast<double>(GPS_L2_M_CODE_RATE_HZ) / static_cast<double>(GPS_L2_M_CODE_LENGTH_CHIPS))); | ||||
|     trk_param_fpga.vector_length = vector_length; | ||||
|     int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); | ||||
|     if (symbols_extended_correlator != 1) | ||||
|         { | ||||
|             std::cout << TEXT_RED << "WARNING: Extended coherent integration is not allowed in GPS L2. Coherent integration has been set to 20 ms (1 symbol)" << TEXT_RESET << std::endl; | ||||
|         } | ||||
|     trk_param_fpga.extend_correlation_symbols = 1; | ||||
|     bool track_pilot = configuration->property(role + ".track_pilot", false); | ||||
|     if (track_pilot) | ||||
|         { | ||||
|             std::cout << TEXT_RED << "WARNING: GPS L2 does not have pilot signal. Data tracking has been enabled" << TEXT_RESET << std::endl; | ||||
|         } | ||||
|     trk_param_fpga.track_pilot = false; | ||||
|     trk_param_fpga.very_early_late_space_chips = 0.0; | ||||
|     trk_param_fpga.very_early_late_space_narrow_chips = 0.0; | ||||
|     trk_param_fpga.pll_bw_narrow_hz = 0.0; | ||||
|     trk_param_fpga.dll_bw_narrow_hz = 0.0; | ||||
|     trk_param_fpga.system = 'G'; | ||||
|     char sig_[3] = "2S"; | ||||
|     std::memcpy(trk_param_fpga.signal, sig_, 3); | ||||
|     int cn0_samples = configuration->property(role + ".cn0_samples", 20); | ||||
|     if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; | ||||
|     trk_param_fpga.cn0_samples = cn0_samples; | ||||
|     int cn0_min = configuration->property(role + ".cn0_min", 25); | ||||
|     if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; | ||||
|     trk_param_fpga.cn0_min = cn0_min; | ||||
|     int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); | ||||
|     if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; | ||||
|     trk_param_fpga.max_lock_fail = max_lock_fail; | ||||
|     double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); | ||||
|     if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; | ||||
|     trk_param_fpga.carrier_lock_th = carrier_lock_th; | ||||
|  | ||||
|     // FPGA configuration parameters | ||||
|     std::string default_device_name = "/dev/uio"; | ||||
|     std::string device_name = configuration->property(role + ".devicename", default_device_name); | ||||
|     trk_param_fpga.device_name = device_name; | ||||
|     unsigned int device_base = configuration->property(role + ".device_base", 1); | ||||
|     trk_param_fpga.device_base = device_base; | ||||
|     //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0); | ||||
|     trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators | ||||
|  | ||||
|     //d_tracking_code = static_cast<float *>(volk_gnsssdr_malloc(2 * static_cast<unsigned int>(GPS_L2_M_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); | ||||
|     d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<unsigned int>(GPS_L2_M_CODE_LENGTH_CHIPS)* NUM_PRNs * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|     float* ca_codes_f = static_cast<float*>(volk_gnsssdr_malloc(static_cast<unsigned int>(GPS_L2_M_CODE_LENGTH_CHIPS)* sizeof(float), volk_gnsssdr_get_alignment())); | ||||
|  | ||||
|     //################# PRE-COMPUTE ALL THE CODES ################# | ||||
|     d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(GPS_L2_M_CODE_LENGTH_CHIPS*NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|     for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) | ||||
|     { | ||||
|         //gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0); | ||||
|         gps_l2c_m_code_gen_float(ca_codes_f, PRN); | ||||
|         for (unsigned int s = 0; s < 2*static_cast<unsigned int>(GPS_L2_M_CODE_LENGTH_CHIPS); s++) | ||||
|             { | ||||
|                 d_ca_codes[static_cast<int>(GPS_L2_M_CODE_LENGTH_CHIPS)* (PRN - 1) + s] = static_cast<int>(ca_codes_f[s]); | ||||
|             } | ||||
|     } | ||||
|  | ||||
|     delete[] ca_codes_f; | ||||
|  | ||||
|     trk_param_fpga.ca_codes = d_ca_codes; | ||||
|     trk_param_fpga.code_length_chips = GPS_L2_M_CODE_LENGTH_CHIPS; | ||||
|     trk_param_fpga.code_samples_per_chip = 1; // 1 sample per chip | ||||
|  | ||||
|     //################# MAKE TRACKING GNURadio object ################### | ||||
|  | ||||
| //    //################# MAKE TRACKING GNURadio object ################### | ||||
| //    if (item_type.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            item_size_ = sizeof(gr_complex); | ||||
| //            tracking_ = dll_pll_veml_make_tracking(trk_param); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            item_size_ = sizeof(gr_complex); | ||||
| //            LOG(WARNING) << item_type << " unknown tracking item type."; | ||||
| //        } | ||||
|  | ||||
|     //################# MAKE TRACKING GNURadio object ################### | ||||
|     tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); | ||||
|  | ||||
|     channel_ = 0; | ||||
|     DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; | ||||
| } | ||||
|  | ||||
|  | ||||
| GpsL2MDllPllTrackingFpga::~GpsL2MDllPllTrackingFpga() | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL2MDllPllTrackingFpga::start_tracking() | ||||
| { | ||||
|     //tracking_->start_tracking(); | ||||
|     tracking_fpga_sc->start_tracking(); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Set tracking channel unique ID | ||||
|  */ | ||||
| void GpsL2MDllPllTrackingFpga::set_channel(unsigned int channel) | ||||
| { | ||||
|     channel_ = channel; | ||||
|     //tracking_->set_channel(channel); | ||||
|     tracking_fpga_sc->set_channel(channel); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL2MDllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) | ||||
| { | ||||
|     //tracking_->set_gnss_synchro(p_gnss_synchro); | ||||
|     tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL2MDllPllTrackingFpga::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 GpsL2MDllPllTrackingFpga::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 GpsL2MDllPllTrackingFpga::get_left_block() | ||||
| { | ||||
|     //return tracking_; | ||||
|     return tracking_fpga_sc; | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GpsL2MDllPllTrackingFpga::get_right_block() | ||||
| { | ||||
|     //return tracking_; | ||||
|     return tracking_fpga_sc; | ||||
| } | ||||
| @@ -0,0 +1,106 @@ | ||||
| /*! | ||||
|  * \file gps_l2_m_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 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 <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_gps_l2_m_dll_pll_tracking_FPGA_H_ | ||||
| #define GNSS_SDR_gps_l2_m_dll_pll_tracking_FPGA_H_ | ||||
|  | ||||
| #include "tracking_interface.h" | ||||
| //#include "dll_pll_veml_tracking.h" | ||||
| #include "dll_pll_veml_tracking_fpga.h" | ||||
| #include <string> | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| /*! | ||||
|  * \brief This class implements a code DLL + carrier PLL tracking loop | ||||
|  */ | ||||
| class GpsL2MDllPllTrackingFpga : public TrackingInterface | ||||
| { | ||||
| public: | ||||
|     GpsL2MDllPllTrackingFpga(ConfigurationInterface* configuration, | ||||
|         std::string role, | ||||
|         unsigned int in_streams, | ||||
|         unsigned int out_streams); | ||||
|  | ||||
|     virtual ~GpsL2MDllPllTrackingFpga(); | ||||
|  | ||||
|     inline std::string role() override | ||||
|     { | ||||
|         return role_; | ||||
|     } | ||||
|  | ||||
|     //! Returns "GPS_L2_M_DLL_PLL_Tracking" | ||||
|     inline std::string implementation() override | ||||
|     { | ||||
|         return "GPS_L2_M_DLL_PLL_Tracking_Fpga"; | ||||
|     } | ||||
|  | ||||
|     inline size_t item_size() override | ||||
|     { | ||||
|         return item_size_; | ||||
|     } | ||||
|  | ||||
|     void connect(gr::top_block_sptr top_block) override; | ||||
|     void disconnect(gr::top_block_sptr top_block) override; | ||||
|     gr::basic_block_sptr get_left_block() override; | ||||
|     gr::basic_block_sptr get_right_block() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set tracking channel unique ID | ||||
|      */ | ||||
|     void set_channel(unsigned int channel) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition/tracking common Gnss_Synchro object pointer | ||||
|      * to efficiently exchange synchronization data between acquisition and tracking blocks | ||||
|      */ | ||||
|     void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; | ||||
|  | ||||
|     void start_tracking() override; | ||||
|  | ||||
| private: | ||||
|     //dll_pll_veml_tracking_sptr tracking_; | ||||
|     dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; | ||||
|     size_t item_size_; | ||||
|     unsigned int channel_; | ||||
|     std::string role_; | ||||
|     unsigned int in_streams_; | ||||
|     unsigned int out_streams_; | ||||
|     int* d_ca_codes; | ||||
| }; | ||||
|  | ||||
| #endif  // GNSS_SDR_gps_l2_m_dll_pll_tracking_FPGA_H_ | ||||
							
								
								
									
										276
									
								
								src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,276 @@ | ||||
| /*! | ||||
|  * \file gps_l5_dll_pll_tracking.cc | ||||
|  * \brief  Interface of an adapter of a DLL+PLL tracking loop block | ||||
|  * for GPS L5 to a TrackingInterface | ||||
|  * \author Javier Arribas, 2017. 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 <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include "gps_l5_dll_pll_tracking_fpga.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "GPS_L5.h" | ||||
| #include "gps_l5_signal.h" | ||||
| #include "gnss_sdr_flags.h" | ||||
| #include "display.h" | ||||
| #include <glog/logging.h> | ||||
|  | ||||
| #define NUM_PRNs 32 | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( | ||||
|     ConfigurationInterface* configuration, std::string role, | ||||
|     unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) | ||||
| { | ||||
| 	//printf("L5 TRK CLASS CREATED\n"); | ||||
|     //dllpllconf_t trk_param; | ||||
| 	Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); | ||||
|     DLOG(INFO) << "role " << role; | ||||
|     //################# CONFIGURATION PARAMETERS ######################## | ||||
|     //std::string default_item_type = "gr_complex"; | ||||
|     //std::string item_type = configuration->property(role + ".item_type", default_item_type); | ||||
|     int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||
|     int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|     trk_param_fpga.fs_in = fs_in; | ||||
|     bool dump = configuration->property(role + ".dump", false); | ||||
|     trk_param_fpga.dump = dump; | ||||
|     float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); | ||||
|     if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz); | ||||
|     trk_param_fpga.pll_bw_hz = pll_bw_hz; | ||||
|     float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); | ||||
|     if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz); | ||||
|     trk_param_fpga.dll_bw_hz = dll_bw_hz; | ||||
|     float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 2.0); | ||||
|     trk_param_fpga.pll_bw_narrow_hz = pll_bw_narrow_hz; | ||||
|     float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 0.25); | ||||
|     trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz; | ||||
|     float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); | ||||
|     trk_param_fpga.early_late_space_chips = early_late_space_chips; | ||||
|     std::string default_dump_filename = "./track_ch"; | ||||
|     std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); | ||||
|     trk_param_fpga.dump_filename = dump_filename; | ||||
|     int vector_length = std::round(static_cast<double>(fs_in) / (static_cast<double>(GPS_L5i_CODE_RATE_HZ) / static_cast<double>(GPS_L5i_CODE_LENGTH_CHIPS))); | ||||
|     trk_param_fpga.vector_length = vector_length; | ||||
|     int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); | ||||
|     float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15); | ||||
|     trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips; | ||||
|     bool track_pilot = configuration->property(role + ".track_pilot", false); | ||||
|     if (extend_correlation_symbols < 1) | ||||
|         { | ||||
|             extend_correlation_symbols = 1; | ||||
|             std::cout << TEXT_RED << "WARNING: GPS L5. extend_correlation_symbols must be bigger than 0. Coherent integration has been set to 1 symbol (1 ms)" << TEXT_RESET << std::endl; | ||||
|         } | ||||
|     else if (!track_pilot and extend_correlation_symbols > GPS_L5i_NH_CODE_LENGTH) | ||||
|         { | ||||
|             extend_correlation_symbols = GPS_L5i_NH_CODE_LENGTH; | ||||
|             std::cout << TEXT_RED << "WARNING: GPS L5. extend_correlation_symbols must be lower than 11 when tracking the data component. Coherent integration has been set to 10 symbols (10 ms)" << TEXT_RESET << std::endl; | ||||
|         } | ||||
|     if ((extend_correlation_symbols > 1) and (pll_bw_narrow_hz > pll_bw_hz or dll_bw_narrow_hz > dll_bw_hz)) | ||||
|         { | ||||
|             std::cout << TEXT_RED << "WARNING: GPS L5. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << std::endl; | ||||
|         } | ||||
|     trk_param_fpga.extend_correlation_symbols = extend_correlation_symbols; | ||||
|     trk_param_fpga.track_pilot = track_pilot; | ||||
|     d_track_pilot = track_pilot; | ||||
|     trk_param_fpga.very_early_late_space_chips = 0.0; | ||||
|     trk_param_fpga.very_early_late_space_narrow_chips = 0.0; | ||||
|     trk_param_fpga.system = 'G'; | ||||
|     char sig_[3] = "L5"; | ||||
|     std::memcpy(trk_param_fpga.signal, sig_, 3); | ||||
|     int cn0_samples = configuration->property(role + ".cn0_samples", 20); | ||||
|     if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; | ||||
|     trk_param_fpga.cn0_samples = cn0_samples; | ||||
|     int cn0_min = configuration->property(role + ".cn0_min", 25); | ||||
|     if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; | ||||
|     trk_param_fpga.cn0_min = cn0_min; | ||||
|     int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); | ||||
|     if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; | ||||
|     trk_param_fpga.max_lock_fail = max_lock_fail; | ||||
|     double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); | ||||
|     if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; | ||||
|     trk_param_fpga.carrier_lock_th = carrier_lock_th; | ||||
|  | ||||
|     // FPGA configuration parameters | ||||
|     std::string default_device_name = "/dev/uio"; | ||||
|     std::string device_name = configuration->property(role + ".devicename", default_device_name); | ||||
|     trk_param_fpga.device_name = device_name; | ||||
|     unsigned int device_base = configuration->property(role + ".device_base", 1); | ||||
|     trk_param_fpga.device_base = device_base; | ||||
|     //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0); | ||||
|     trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators | ||||
|  | ||||
|     //################# PRE-COMPUTE ALL THE CODES ################# | ||||
|     unsigned int code_samples_per_chip = 1; | ||||
|     unsigned int code_length_chips = static_cast<unsigned int>(GPS_L5i_CODE_LENGTH_CHIPS); | ||||
|     //printf("TRK code_length_chips = %d\n", code_length_chips); | ||||
|  | ||||
|     float *tracking_code; | ||||
|     float *data_code; | ||||
|  | ||||
|     tracking_code = static_cast<float *>(volk_gnsssdr_malloc(code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); | ||||
|  | ||||
|     if (trk_param_fpga.track_pilot) | ||||
|     { | ||||
|     	data_code = static_cast<float *>(volk_gnsssdr_malloc(code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); | ||||
|     } | ||||
|  | ||||
|     d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(code_length_chips*NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|  | ||||
|     if (trk_param_fpga.track_pilot) | ||||
|         { | ||||
|             d_data_codes = static_cast<int *>(volk_gnsssdr_malloc((static_cast<unsigned int>(code_length_chips)) * NUM_PRNs * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|         } | ||||
|  | ||||
|     //printf("start \n"); | ||||
|     for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) | ||||
|     { | ||||
|  | ||||
| 		if (track_pilot) | ||||
| 			{ | ||||
|  | ||||
| 				gps_l5q_code_gen_float(tracking_code, PRN); | ||||
| 				gps_l5i_code_gen_float(data_code, PRN); | ||||
|  | ||||
|  | ||||
| 				for (unsigned int s = 0; s < code_length_chips; s++) | ||||
| 					{ | ||||
| 						d_ca_codes[static_cast<int>(code_length_chips)* (PRN - 1) + s] = static_cast<int>(tracking_code[s]); | ||||
| 						d_data_codes[static_cast<int>(code_length_chips)* (PRN - 1) + s] = static_cast<int>(data_code[s]); | ||||
| 						//printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); | ||||
|  | ||||
| 					} | ||||
| 			} | ||||
|  | ||||
| 		else | ||||
| 			{ | ||||
|  | ||||
| 				gps_l5i_code_gen_float(tracking_code, PRN); | ||||
|                 for (unsigned int s = 0; s < code_length_chips; s++) | ||||
|                     { | ||||
|                         d_ca_codes[static_cast<int>(code_length_chips) * (PRN - 1) + s] = static_cast<int>(data_code[s]); | ||||
|                         //printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); | ||||
|                     } | ||||
| 			} | ||||
|     } | ||||
|     //printf("end \n"); | ||||
|  | ||||
|  | ||||
|     delete[] tracking_code; | ||||
|     if (trk_param_fpga.track_pilot) | ||||
|         { | ||||
|             delete[] data_code; | ||||
|         } | ||||
|     trk_param_fpga.ca_codes = d_ca_codes; | ||||
|     trk_param_fpga.data_codes = d_data_codes; | ||||
|     trk_param_fpga.code_length_chips = code_length_chips; | ||||
|     trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip | ||||
|     //################# MAKE TRACKING GNURadio object ################### | ||||
| //    if (item_type.compare("gr_complex") == 0) | ||||
| //        { | ||||
| //            item_size_ = sizeof(gr_complex); | ||||
| //            tracking_ = dll_pll_veml_make_tracking(trk_param_fpga); | ||||
| //        } | ||||
| //    else | ||||
| //        { | ||||
| //            item_size_ = sizeof(gr_complex); | ||||
| //            LOG(WARNING) << item_type << " unknown tracking item type."; | ||||
| //        } | ||||
|     //printf("call \n"); | ||||
|     tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); | ||||
|     //printf("end2 \n"); | ||||
|     channel_ = 0; | ||||
|     DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; | ||||
| } | ||||
|  | ||||
|  | ||||
| GpsL5DllPllTrackingFpga::~GpsL5DllPllTrackingFpga() | ||||
| { | ||||
|  | ||||
|     delete[] d_ca_codes; | ||||
|     if (d_track_pilot) | ||||
|         { | ||||
|             delete[] d_data_codes; | ||||
|  | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL5DllPllTrackingFpga::start_tracking() | ||||
| { | ||||
| 	tracking_fpga_sc->start_tracking(); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Set tracking channel unique ID | ||||
|  */ | ||||
| void GpsL5DllPllTrackingFpga::set_channel(unsigned int channel) | ||||
| { | ||||
|     channel_ = channel; | ||||
|     tracking_fpga_sc->set_channel(channel); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL5DllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) | ||||
| { | ||||
| 	tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GpsL5DllPllTrackingFpga::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 GpsL5DllPllTrackingFpga::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 GpsL5DllPllTrackingFpga::get_left_block() | ||||
| { | ||||
|     return tracking_fpga_sc; | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr GpsL5DllPllTrackingFpga::get_right_block() | ||||
| { | ||||
|     return tracking_fpga_sc; | ||||
| } | ||||
							
								
								
									
										106
									
								
								src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| /*! | ||||
|  * \file gps_l5_dll_pll_tracking.h | ||||
|  * \brief  Interface of an adapter of a DLL+PLL tracking loop block | ||||
|  * for GPS L5 to a TrackingInterface | ||||
|  * \author Javier Arribas, 2017. 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 <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_GPS_L5_DLL_PLL_TRACKING_FPGA_H_ | ||||
| #define GNSS_SDR_GPS_L5_DLL_PLL_TRACKING_FPGA_H_ | ||||
|  | ||||
| #include "tracking_interface.h" | ||||
| #include "dll_pll_veml_tracking_fpga.h" | ||||
| #include <string> | ||||
|  | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| /*! | ||||
|  * \brief This class implements a code DLL + carrier PLL tracking loop | ||||
|  */ | ||||
| class GpsL5DllPllTrackingFpga : public TrackingInterface | ||||
| { | ||||
| public: | ||||
|     GpsL5DllPllTrackingFpga(ConfigurationInterface* configuration, | ||||
|         std::string role, | ||||
|         unsigned int in_streams, | ||||
|         unsigned int out_streams); | ||||
|  | ||||
|     virtual ~GpsL5DllPllTrackingFpga(); | ||||
|  | ||||
|     inline std::string role() override | ||||
|     { | ||||
|         return role_; | ||||
|     } | ||||
|  | ||||
|     //! Returns "GPS_L5_DLL_PLL_Tracking" | ||||
|     inline std::string implementation() override | ||||
|     { | ||||
|         return "GPS_L5_DLL_PLL_Tracking"; | ||||
|     } | ||||
|  | ||||
|     inline size_t item_size() override | ||||
|     { | ||||
|         return item_size_; | ||||
|     } | ||||
|  | ||||
|     void connect(gr::top_block_sptr top_block) override; | ||||
|     void disconnect(gr::top_block_sptr top_block) override; | ||||
|     gr::basic_block_sptr get_left_block() override; | ||||
|     gr::basic_block_sptr get_right_block() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set tracking channel unique ID | ||||
|      */ | ||||
|     void set_channel(unsigned int channel) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Set acquisition/tracking common Gnss_Synchro object pointer | ||||
|      * to efficiently exchange synchronization data between acquisition and tracking blocks | ||||
|      */ | ||||
|     void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; | ||||
|  | ||||
|     void start_tracking() override; | ||||
|  | ||||
| private: | ||||
|     //dll_pll_veml_tracking_sptr tracking_; | ||||
|     dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; | ||||
|     size_t item_size_; | ||||
|     unsigned int channel_; | ||||
|     std::string role_; | ||||
|     unsigned int in_streams_; | ||||
|     unsigned int out_streams_; | ||||
|     bool d_track_pilot; | ||||
|     int* d_ca_codes; | ||||
|     int* d_data_codes; | ||||
| }; | ||||
|  | ||||
| #endif  // GNSS_SDR_GPS_L5_DLL_PLL_TRACKING_FPGA_H_ | ||||
| @@ -94,6 +94,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl | ||||
|     d_code_chip_rate = 0.0; | ||||
|     d_secondary_code_length = 0; | ||||
|     d_secondary_code_string = nullptr; | ||||
|     d_gps_l1ca_preambles_symbols = nullptr; | ||||
|     signal_type = std::string(trk_parameters.signal); | ||||
|  | ||||
|     std::map<std::string, std::string> map_signal_pretty_name; | ||||
| @@ -118,21 +119,21 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl | ||||
|                     d_symbols_per_bit = GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; | ||||
|                     d_correlation_length_ms = 1; | ||||
|                     d_code_samples_per_chip = 1; | ||||
|                     d_code_length_chips = static_cast<unsigned int>(GPS_L1_CA_CODE_LENGTH_CHIPS); | ||||
|                     d_code_length_chips = static_cast<uint32_t>(GPS_L1_CA_CODE_LENGTH_CHIPS); | ||||
|                     // GPS L1 C/A does not have pilot component nor secondary code | ||||
|                     d_secondary = false; | ||||
|                     trk_parameters.track_pilot = false; | ||||
|                     interchange_iq = false; | ||||
|  | ||||
|                     // set the preamble | ||||
|                     unsigned short int preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE; | ||||
|                     uint16_t preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE; | ||||
|  | ||||
|                     // preamble bits to sampled symbols | ||||
|                     d_gps_l1ca_preambles_symbols = static_cast<int *>(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|                     int n = 0; | ||||
|                     for (int i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++) | ||||
|                     d_gps_l1ca_preambles_symbols = static_cast<int32_t *>(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int32_t), volk_gnsssdr_get_alignment())); | ||||
|                     int32_t n = 0; | ||||
|                     for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++) | ||||
|                         { | ||||
|                             for (unsigned int j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++) | ||||
|                             for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++) | ||||
|                                 { | ||||
|                                     if (preambles_bits[i] == 1) | ||||
|                                         { | ||||
| @@ -153,7 +154,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl | ||||
|                     d_signal_carrier_freq = GPS_L2_FREQ_HZ; | ||||
|                     d_code_period = GPS_L2_M_PERIOD; | ||||
|                     d_code_chip_rate = GPS_L2_M_CODE_RATE_HZ; | ||||
|                     d_code_length_chips = static_cast<unsigned int>(GPS_L2_M_CODE_LENGTH_CHIPS); | ||||
|                     d_code_length_chips = static_cast<uint32_t>(GPS_L2_M_CODE_LENGTH_CHIPS); | ||||
|                     d_symbols_per_bit = GPS_L2_SAMPLES_PER_SYMBOL; | ||||
|                     d_correlation_length_ms = 20; | ||||
|                     d_code_samples_per_chip = 1; | ||||
| @@ -170,18 +171,18 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl | ||||
|                     d_symbols_per_bit = GPS_L5_SAMPLES_PER_SYMBOL; | ||||
|                     d_correlation_length_ms = 1; | ||||
|                     d_code_samples_per_chip = 1; | ||||
|                     d_code_length_chips = static_cast<unsigned int>(GPS_L5i_CODE_LENGTH_CHIPS); | ||||
|                     d_code_length_chips = static_cast<uint32_t>(GPS_L5i_CODE_LENGTH_CHIPS); | ||||
|                     d_secondary = true; | ||||
|                     if (trk_parameters.track_pilot) | ||||
|                         { | ||||
|                             d_secondary_code_length = static_cast<unsigned int>(GPS_L5q_NH_CODE_LENGTH); | ||||
|                             d_secondary_code_length = static_cast<uint32_t>(GPS_L5q_NH_CODE_LENGTH); | ||||
|                             d_secondary_code_string = const_cast<std::string *>(&GPS_L5q_NH_CODE_STR); | ||||
|                             signal_pretty_name = signal_pretty_name + "Q"; | ||||
|                             interchange_iq = true; | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             d_secondary_code_length = static_cast<unsigned int>(GPS_L5i_NH_CODE_LENGTH); | ||||
|                             d_secondary_code_length = static_cast<uint32_t>(GPS_L5i_NH_CODE_LENGTH); | ||||
|                             d_secondary_code_string = const_cast<std::string *>(&GPS_L5i_NH_CODE_STR); | ||||
|                             signal_pretty_name = signal_pretty_name + "I"; | ||||
|                             interchange_iq = false; | ||||
| @@ -209,7 +210,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl | ||||
|                     d_signal_carrier_freq = Galileo_E1_FREQ_HZ; | ||||
|                     d_code_period = Galileo_E1_CODE_PERIOD; | ||||
|                     d_code_chip_rate = Galileo_E1_CODE_CHIP_RATE_HZ; | ||||
|                     d_code_length_chips = static_cast<unsigned int>(Galileo_E1_B_CODE_LENGTH_CHIPS); | ||||
|                     d_code_length_chips = static_cast<uint32_t>(Galileo_E1_B_CODE_LENGTH_CHIPS); | ||||
|                     d_symbols_per_bit = 1; | ||||
|                     d_correlation_length_ms = 4; | ||||
|                     d_code_samples_per_chip = 2;  // CBOC disabled: 2 samples per chip. CBOC enabled: 12 samples per chip | ||||
| @@ -217,7 +218,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl | ||||
|                     if (trk_parameters.track_pilot) | ||||
|                         { | ||||
|                             d_secondary = true; | ||||
|                             d_secondary_code_length = static_cast<unsigned int>(Galileo_E1_C_SECONDARY_CODE_LENGTH); | ||||
|                             d_secondary_code_length = static_cast<uint32_t>(Galileo_E1_C_SECONDARY_CODE_LENGTH); | ||||
|                             d_secondary_code_string = const_cast<std::string *>(&Galileo_E1_C_SECONDARY_CODE); | ||||
|                             signal_pretty_name = signal_pretty_name + "C"; | ||||
|                         } | ||||
| @@ -236,17 +237,17 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl | ||||
|                     d_symbols_per_bit = 20; | ||||
|                     d_correlation_length_ms = 1; | ||||
|                     d_code_samples_per_chip = 1; | ||||
|                     d_code_length_chips = static_cast<unsigned int>(Galileo_E5a_CODE_LENGTH_CHIPS); | ||||
|                     d_code_length_chips = static_cast<uint32_t>(Galileo_E5a_CODE_LENGTH_CHIPS); | ||||
|                     d_secondary = true; | ||||
|                     if (trk_parameters.track_pilot) | ||||
|                         { | ||||
|                             d_secondary_code_length = static_cast<unsigned int>(Galileo_E5a_Q_SECONDARY_CODE_LENGTH); | ||||
|                             d_secondary_code_length = static_cast<uint32_t>(Galileo_E5a_Q_SECONDARY_CODE_LENGTH); | ||||
|                             signal_pretty_name = signal_pretty_name + "Q"; | ||||
|                             interchange_iq = true; | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             d_secondary_code_length = static_cast<unsigned int>(Galileo_E5a_I_SECONDARY_CODE_LENGTH); | ||||
|                             d_secondary_code_length = static_cast<uint32_t>(Galileo_E5a_I_SECONDARY_CODE_LENGTH); | ||||
|                             d_secondary_code_string = const_cast<std::string *>(&Galileo_E5a_I_SECONDARY_CODE); | ||||
|                             signal_pretty_name = signal_pretty_name + "I"; | ||||
|                             interchange_iq = false; | ||||
| @@ -494,7 +495,7 @@ void dll_pll_veml_tracking::start_tracking() | ||||
|             if (trk_parameters.track_pilot) | ||||
|                 { | ||||
|                     d_secondary_code_string = const_cast<std::string *>(&Galileo_E5a_Q_SECONDARY_CODE[d_acquisition_gnss_synchro->PRN - 1]); | ||||
|                     for (unsigned int i = 0; i < d_code_length_chips; i++) | ||||
|                     for (uint32_t i = 0; i < d_code_length_chips; i++) | ||||
|                         { | ||||
|                             d_tracking_code[i] = aux_code[i].imag(); | ||||
|                             d_data_code[i] = aux_code[i].real(); | ||||
| @@ -504,7 +505,7 @@ void dll_pll_veml_tracking::start_tracking() | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     for (unsigned int i = 0; i < d_code_length_chips; i++) | ||||
|                     for (uint32_t i = 0; i < d_code_length_chips; i++) | ||||
|                         { | ||||
|                             d_tracking_code[i] = aux_code[i].real(); | ||||
|                         } | ||||
| @@ -612,8 +613,8 @@ dll_pll_veml_tracking::~dll_pll_veml_tracking() | ||||
| bool dll_pll_veml_tracking::acquire_secondary() | ||||
| { | ||||
|     // ******* preamble correlation ******** | ||||
|     int corr_value = 0; | ||||
|     for (unsigned int i = 0; i < d_secondary_code_length; i++) | ||||
|     int32_t corr_value = 0; | ||||
|     for (uint32_t i = 0; i < d_secondary_code_length; i++) | ||||
|         { | ||||
|             if (d_Prompt_buffer_deque.at(i).real() < 0.0)  // symbols clipping | ||||
|                 { | ||||
| @@ -967,8 +968,8 @@ void dll_pll_veml_tracking::log_data(bool integrating) | ||||
|                     tmp_double = static_cast<double>(d_sample_counter + d_current_prn_length_samples); | ||||
|                     d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double)); | ||||
|                     // PRN | ||||
|                     unsigned int prn_ = d_acquisition_gnss_synchro->PRN; | ||||
|                     d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int)); | ||||
|                     uint32_t prn_ = d_acquisition_gnss_synchro->PRN; | ||||
|                     d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(uint32_t)); | ||||
|                 } | ||||
|             catch (const std::ifstream::failure &e) | ||||
|                 { | ||||
| @@ -978,14 +979,14 @@ void dll_pll_veml_tracking::log_data(bool integrating) | ||||
| } | ||||
|  | ||||
|  | ||||
| int dll_pll_veml_tracking::save_matfile() | ||||
| int32_t dll_pll_veml_tracking::save_matfile() | ||||
| { | ||||
|     // READ DUMP FILE | ||||
|     std::ifstream::pos_type size; | ||||
|     int number_of_double_vars = 1; | ||||
|     int number_of_float_vars = 17; | ||||
|     int epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + | ||||
|                            sizeof(float) * number_of_float_vars + sizeof(unsigned int); | ||||
|     int32_t number_of_double_vars = 1; | ||||
|     int32_t number_of_float_vars = 17; | ||||
|     int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + | ||||
|                                sizeof(float) * number_of_float_vars + sizeof(uint32_t); | ||||
|     std::ifstream dump_file; | ||||
|     dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); | ||||
|     try | ||||
| @@ -1028,7 +1029,7 @@ int dll_pll_veml_tracking::save_matfile() | ||||
|     float *carrier_lock_test = new float[num_epoch]; | ||||
|     float *aux1 = new float[num_epoch]; | ||||
|     double *aux2 = new double[num_epoch]; | ||||
|     unsigned int *PRN = new unsigned int[num_epoch]; | ||||
|     uint32_t *PRN = new uint32_t[num_epoch]; | ||||
|  | ||||
|     try | ||||
|         { | ||||
| @@ -1055,7 +1056,7 @@ int dll_pll_veml_tracking::save_matfile() | ||||
|                             dump_file.read(reinterpret_cast<char *>(&carrier_lock_test[i]), sizeof(float)); | ||||
|                             dump_file.read(reinterpret_cast<char *>(&aux1[i]), sizeof(float)); | ||||
|                             dump_file.read(reinterpret_cast<char *>(&aux2[i]), sizeof(double)); | ||||
|                             dump_file.read(reinterpret_cast<char *>(&PRN[i]), sizeof(unsigned int)); | ||||
|                             dump_file.read(reinterpret_cast<char *>(&PRN[i]), sizeof(uint32_t)); | ||||
|                         } | ||||
|                 } | ||||
|             dump_file.close(); | ||||
| @@ -1201,7 +1202,7 @@ int dll_pll_veml_tracking::save_matfile() | ||||
| } | ||||
|  | ||||
|  | ||||
| void dll_pll_veml_tracking::set_channel(unsigned int channel) | ||||
| void dll_pll_veml_tracking::set_channel(uint32_t channel) | ||||
| { | ||||
|     gr::thread::scoped_lock l(d_setlock); | ||||
|     d_channel = channel; | ||||
| @@ -1257,7 +1258,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) | ||||
|                 // Signal alignment (skip samples until the incoming signal is aligned with local replica) | ||||
|                 uint64_t acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; | ||||
|                 double acq_trk_shif_correction_samples = static_cast<double>(d_current_prn_length_samples) - std::fmod(static_cast<double>(acq_to_trk_delay_samples), static_cast<double>(d_current_prn_length_samples)); | ||||
|                 int samples_offset = std::round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); | ||||
|                 int32_t samples_offset = std::round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); | ||||
|                 if (samples_offset < 0) | ||||
|                     { | ||||
|                         samples_offset = 0; | ||||
| @@ -1319,10 +1320,10 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) | ||||
|                                     { | ||||
|                                         d_symbol_history.push_back(d_Prompt->real()); | ||||
|                                         //******* preamble correlation ******** | ||||
|                                         int corr_value = 0; | ||||
|                                         int32_t corr_value = 0; | ||||
|                                         if ((d_symbol_history.size() == GPS_CA_PREAMBLE_LENGTH_SYMBOLS))  // and (d_make_correlation or !d_flag_frame_sync)) | ||||
|                                             { | ||||
|                                                 for (unsigned int i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++) | ||||
|                                                 for (uint32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++) | ||||
|                                                     { | ||||
|                                                         if (d_symbol_history.at(i) < 0)  // symbols clipping | ||||
|                                                             { | ||||
| @@ -1563,7 +1564,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) | ||||
|             } | ||||
|         } | ||||
|     consume_each(d_current_prn_length_samples); | ||||
|     d_sample_counter += d_current_prn_length_samples; | ||||
|     d_sample_counter += static_cast<uint64_t>(d_current_prn_length_samples); | ||||
|     if (current_synchro_data.Flag_valid_symbol_output) | ||||
|         { | ||||
|             current_synchro_data.fs = static_cast<int64_t>(trk_parameters.fs_in); | ||||
|   | ||||
| @@ -57,7 +57,7 @@ class dll_pll_veml_tracking : public gr::block | ||||
| public: | ||||
|     ~dll_pll_veml_tracking(); | ||||
|  | ||||
|     void set_channel(unsigned int channel); | ||||
|     void set_channel(uint32_t channel); | ||||
|     void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro); | ||||
|     void start_tracking(); | ||||
|  | ||||
| @@ -80,13 +80,13 @@ private: | ||||
|     void clear_tracking_vars(); | ||||
|     void save_correlation_results(); | ||||
|     void log_data(bool integrating); | ||||
|     int save_matfile(); | ||||
|     int32_t save_matfile(); | ||||
|  | ||||
|     // tracking configuration vars | ||||
|     Dll_Pll_Conf trk_parameters; | ||||
|     bool d_veml; | ||||
|     bool d_cloop; | ||||
|     unsigned int d_channel; | ||||
|     uint32_t d_channel; | ||||
|     Gnss_Synchro *d_acquisition_gnss_synchro; | ||||
|  | ||||
|     //Signal parameters | ||||
| @@ -95,24 +95,23 @@ private: | ||||
|     double d_signal_carrier_freq; | ||||
|     double d_code_period; | ||||
|     double d_code_chip_rate; | ||||
|     unsigned int d_secondary_code_length; | ||||
|     unsigned int d_code_length_chips; | ||||
|     unsigned int d_code_samples_per_chip;  // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled) | ||||
|     int d_symbols_per_bit; | ||||
|     uint32_t d_secondary_code_length; | ||||
|     uint32_t d_code_length_chips; | ||||
|     uint32_t d_code_samples_per_chip;  // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled) | ||||
|     int32_t d_symbols_per_bit; | ||||
|     std::string systemName; | ||||
|     std::string signal_type; | ||||
|     std::string *d_secondary_code_string; | ||||
|     std::string signal_pretty_name; | ||||
|  | ||||
|     uint64_t d_preamble_sample_counter; | ||||
|     int *d_gps_l1ca_preambles_symbols; | ||||
|     int32_t *d_gps_l1ca_preambles_symbols; | ||||
|     boost::circular_buffer<float> d_symbol_history; | ||||
|  | ||||
|     //tracking state machine | ||||
|     int d_state; | ||||
|     int32_t d_state; | ||||
|     //Integration period in samples | ||||
|     int d_correlation_length_ms; | ||||
|     int d_n_correlator_taps; | ||||
|     int32_t d_correlation_length_ms; | ||||
|     int32_t d_n_correlator_taps; | ||||
|  | ||||
|     float *d_tracking_code; | ||||
|     float *d_data_code; | ||||
| @@ -133,8 +132,8 @@ private: | ||||
|     gr_complex *d_Very_Late; | ||||
|  | ||||
|     bool d_enable_extended_integration; | ||||
|     int d_extend_correlation_symbols_count; | ||||
|     int d_current_symbol; | ||||
|     int32_t d_extend_correlation_symbols_count; | ||||
|     int32_t d_current_symbol; | ||||
|  | ||||
|     gr_complex d_VE_accu; | ||||
|     gr_complex d_E_accu; | ||||
| @@ -175,14 +174,14 @@ private: | ||||
|     double T_prn_samples; | ||||
|     double K_blk_samples; | ||||
|     // PRN period in samples | ||||
|     int d_current_prn_length_samples; | ||||
|     int32_t d_current_prn_length_samples; | ||||
|     // processing samples counters | ||||
|     uint64_t d_sample_counter; | ||||
|     uint64_t d_acq_sample_stamp; | ||||
|  | ||||
|     // CN0 estimation and lock detector | ||||
|     int d_cn0_estimation_counter; | ||||
|     int d_carrier_lock_fail_counter; | ||||
|     int32_t d_cn0_estimation_counter; | ||||
|     int32_t d_carrier_lock_fail_counter; | ||||
|     std::deque<float> d_carrier_lock_detector_queue; | ||||
|     double d_carrier_lock_test; | ||||
|     double d_CN0_SNV_dB_Hz; | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| /*! | ||||
|  * \file dll_pll_veml_tracking.cc | ||||
|  * \file dll_pll_veml_tracking_fpga.cc | ||||
|  * \brief Implementation of a code DLL + carrier PLL tracking block using an FPGA | ||||
|  * \author Marc Majoral, 2018. marc.majoral(at)cttc.es | ||||
|  * 	       Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com | ||||
|  * 		   Javier Arribas, 2018. 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, | ||||
| @@ -56,15 +57,16 @@ | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
|  | ||||
|  | ||||
| using google::LogMessage; | ||||
|  | ||||
| dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
| dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_) | ||||
| { | ||||
|     return dll_pll_veml_tracking_fpga_sptr(new dll_pll_veml_tracking_fpga(conf_)); | ||||
| } | ||||
|  | ||||
|  | ||||
| dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) : gr::block("dll_pll_veml_tracking_fpga", gr::io_signature::make(0, 0, sizeof(lv_16sc_t)), | ||||
| dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_) : gr::block("dll_pll_veml_tracking_fpga", gr::io_signature::make(0, 0, sizeof(lv_16sc_t)), | ||||
|                                                                                              gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) | ||||
| { | ||||
|     trk_parameters = conf_; | ||||
| @@ -72,6 +74,9 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|     this->message_port_register_out(pmt::mp("events")); | ||||
|     this->set_relative_rate(1.0 / static_cast<double>(trk_parameters.vector_length)); | ||||
|  | ||||
|     // Telemetry bit synchronization message port input (mainly for GPS L1 CA) | ||||
|     this->message_port_register_in(pmt::mp("preamble_samplestamp")); | ||||
|  | ||||
|     // initialize internal vars | ||||
|     d_veml = false; | ||||
|     d_cloop = true; | ||||
| @@ -92,6 +97,9 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|  | ||||
|     signal_pretty_name = map_signal_pretty_name[signal_type]; | ||||
|  | ||||
|  | ||||
|     d_prompt_data_shift = nullptr; | ||||
|  | ||||
|     if (trk_parameters.system == 'G') | ||||
|         { | ||||
|             systemName = "GPS"; | ||||
| @@ -102,22 +110,47 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|                     d_code_chip_rate = GPS_L1_CA_CODE_RATE_HZ; | ||||
|                     d_symbols_per_bit = GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; | ||||
|                     d_correlation_length_ms = 1; | ||||
|                     d_code_samples_per_chip = 1; | ||||
|                     d_code_length_chips = static_cast<unsigned int>(GPS_L1_CA_CODE_LENGTH_CHIPS); | ||||
|                     //d_code_samples_per_chip = 1; | ||||
|                     //d_code_length_chips = static_cast<uint32_t >(GPS_L1_CA_CODE_LENGTH_CHIPS); | ||||
|                     // GPS L1 C/A does not have pilot component nor secondary code | ||||
|                     d_secondary = false; | ||||
|                     trk_parameters.track_pilot = false; | ||||
|                     interchange_iq = false; | ||||
|  | ||||
|  | ||||
|                     // set the preamble | ||||
|                     unsigned short int preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE; | ||||
|  | ||||
|                     // preamble bits to sampled symbols | ||||
|                     d_gps_l1ca_preambles_symbols = static_cast<int *>(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
|                     int n = 0; | ||||
|                     for (int i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++) | ||||
|                         { | ||||
|                             for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++) | ||||
|                                 { | ||||
|                                     if (preambles_bits[i] == 1) | ||||
|                                         { | ||||
|                                             d_gps_l1ca_preambles_symbols[n] = 1; | ||||
|                                         } | ||||
|                                     else | ||||
|                                         { | ||||
|                                             d_gps_l1ca_preambles_symbols[n] = -1; | ||||
|                                         } | ||||
|                                     n++; | ||||
|                                 } | ||||
|                         } | ||||
|                     d_symbol_history.resize(GPS_CA_PREAMBLE_LENGTH_SYMBOLS);  // Change fixed buffer size | ||||
|                     d_symbol_history.clear();                                 // Clear all the elements in the buffer | ||||
|                 } | ||||
|             else if (signal_type.compare("2S") == 0) | ||||
|                 { | ||||
|                     d_signal_carrier_freq = GPS_L2_FREQ_HZ; | ||||
|                     d_code_period = GPS_L2_M_PERIOD; | ||||
|                     d_code_chip_rate = GPS_L2_M_CODE_RATE_HZ; | ||||
|                     d_code_length_chips = static_cast<unsigned int>(GPS_L2_M_CODE_LENGTH_CHIPS); | ||||
|                     //d_code_length_chips = static_cast<uint32_t >(GPS_L2_M_CODE_LENGTH_CHIPS); | ||||
|                     d_symbols_per_bit = GPS_L2_SAMPLES_PER_SYMBOL; | ||||
|                     d_correlation_length_ms = 20; | ||||
|                     d_code_samples_per_chip = 1; | ||||
|                     //d_code_samples_per_chip = 1; | ||||
|                     // GPS L2 does not have pilot component nor secondary code | ||||
|                     d_secondary = false; | ||||
|                     trk_parameters.track_pilot = false; | ||||
| @@ -130,19 +163,20 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|                     d_code_chip_rate = GPS_L5i_CODE_RATE_HZ; | ||||
|                     d_symbols_per_bit = GPS_L5_SAMPLES_PER_SYMBOL; | ||||
|                     d_correlation_length_ms = 1; | ||||
|                     d_code_samples_per_chip = 1; | ||||
|                     d_code_length_chips = static_cast<unsigned int>(GPS_L5i_CODE_LENGTH_CHIPS); | ||||
|                     //d_code_samples_per_chip = 1; | ||||
|                     //d_code_length_chips = static_cast<uint32_t >(GPS_L5i_CODE_LENGTH_CHIPS); | ||||
|                     d_secondary = true; | ||||
|                     //                   interchange_iq = false; | ||||
|                     if (trk_parameters.track_pilot) | ||||
|                         { | ||||
|                             d_secondary_code_length = static_cast<unsigned int>(GPS_L5q_NH_CODE_LENGTH); | ||||
|                             d_secondary_code_length = static_cast<uint32_t>(GPS_L5q_NH_CODE_LENGTH); | ||||
|                             d_secondary_code_string = const_cast<std::string *>(&GPS_L5q_NH_CODE_STR); | ||||
|                             signal_pretty_name = signal_pretty_name + "Q"; | ||||
|                             interchange_iq = true; | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             d_secondary_code_length = static_cast<unsigned int>(GPS_L5i_NH_CODE_LENGTH); | ||||
|                             d_secondary_code_length = static_cast<uint32_t>(GPS_L5i_NH_CODE_LENGTH); | ||||
|                             d_secondary_code_string = const_cast<std::string *>(&GPS_L5i_NH_CODE_STR); | ||||
|                             signal_pretty_name = signal_pretty_name + "I"; | ||||
|                             interchange_iq = false; | ||||
| @@ -157,8 +191,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|                     interchange_iq = false; | ||||
|                     d_signal_carrier_freq = 0.0; | ||||
|                     d_code_period = 0.0; | ||||
|                     d_code_length_chips = 0; | ||||
|                     d_code_samples_per_chip = 0; | ||||
|                     //d_code_length_chips = 0; | ||||
|                     //d_code_samples_per_chip = 0; | ||||
|                     d_symbols_per_bit = 0; | ||||
|                 } | ||||
|         } | ||||
| @@ -170,15 +204,15 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|                     d_signal_carrier_freq = Galileo_E1_FREQ_HZ; | ||||
|                     d_code_period = Galileo_E1_CODE_PERIOD; | ||||
|                     d_code_chip_rate = Galileo_E1_CODE_CHIP_RATE_HZ; | ||||
|                     d_code_length_chips = static_cast<unsigned int>(Galileo_E1_B_CODE_LENGTH_CHIPS); | ||||
|                     //d_code_length_chips = static_cast<uint32_t >(Galileo_E1_B_CODE_LENGTH_CHIPS); | ||||
|                     d_symbols_per_bit = 1; | ||||
|                     d_correlation_length_ms = 4; | ||||
|                     d_code_samples_per_chip = 2;  // CBOC disabled: 2 samples per chip. CBOC enabled: 12 samples per chip | ||||
|                     //d_code_samples_per_chip = 2;  // CBOC disabled: 2 samples per chip. CBOC enabled: 12 samples per chip | ||||
|                     d_veml = true; | ||||
|                     if (trk_parameters.track_pilot) | ||||
|                         { | ||||
|                             d_secondary = true; | ||||
|                             d_secondary_code_length = static_cast<unsigned int>(Galileo_E1_C_SECONDARY_CODE_LENGTH); | ||||
|                             d_secondary_code_length = static_cast<uint32_t>(Galileo_E1_C_SECONDARY_CODE_LENGTH); | ||||
|                             d_secondary_code_string = const_cast<std::string *>(&Galileo_E1_C_SECONDARY_CODE); | ||||
|                             signal_pretty_name = signal_pretty_name + "C"; | ||||
|                         } | ||||
| @@ -196,18 +230,19 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|                     d_code_chip_rate = Galileo_E5a_CODE_CHIP_RATE_HZ; | ||||
|                     d_symbols_per_bit = 20; | ||||
|                     d_correlation_length_ms = 1; | ||||
|                     d_code_samples_per_chip = 1; | ||||
|                     d_code_length_chips = static_cast<unsigned int>(Galileo_E5a_CODE_LENGTH_CHIPS); | ||||
|                     //d_code_samples_per_chip = 1; | ||||
|                     //d_code_length_chips = static_cast<uint32_t >(Galileo_E5a_CODE_LENGTH_CHIPS); | ||||
|                     d_secondary = true; | ||||
|                     //interchange_iq = false; | ||||
|                     if (trk_parameters.track_pilot) | ||||
|                         { | ||||
|                             d_secondary_code_length = static_cast<unsigned int>(Galileo_E5a_Q_SECONDARY_CODE_LENGTH); | ||||
|                             d_secondary_code_length = static_cast<uint32_t>(Galileo_E5a_Q_SECONDARY_CODE_LENGTH); | ||||
|                             signal_pretty_name = signal_pretty_name + "Q"; | ||||
|                             interchange_iq = true; | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             d_secondary_code_length = static_cast<unsigned int>(Galileo_E5a_I_SECONDARY_CODE_LENGTH); | ||||
|                             d_secondary_code_length = static_cast<uint32_t>(Galileo_E5a_I_SECONDARY_CODE_LENGTH); | ||||
|                             d_secondary_code_string = const_cast<std::string *>(&Galileo_E5a_I_SECONDARY_CODE); | ||||
|                             signal_pretty_name = signal_pretty_name + "I"; | ||||
|                             interchange_iq = false; | ||||
| @@ -222,8 +257,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|                     interchange_iq = false; | ||||
|                     d_signal_carrier_freq = 0.0; | ||||
|                     d_code_period = 0.0; | ||||
|                     d_code_length_chips = 0; | ||||
|                     d_code_samples_per_chip = 0; | ||||
|                     //d_code_length_chips = 0; | ||||
|                     //d_code_samples_per_chip = 0; | ||||
|                     d_symbols_per_bit = 0; | ||||
|                 } | ||||
|         } | ||||
| @@ -236,8 +271,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|             interchange_iq = false; | ||||
|             d_signal_carrier_freq = 0.0; | ||||
|             d_code_period = 0.0; | ||||
|             d_code_length_chips = 0; | ||||
|             d_code_samples_per_chip = 0; | ||||
|             //d_code_length_chips = 0; | ||||
|             //d_code_samples_per_chip = 0; | ||||
|             d_symbols_per_bit = 0; | ||||
|         } | ||||
|     T_chip_seconds = 0.0; | ||||
| @@ -246,6 +281,7 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|     K_blk_samples = 0.0; | ||||
|  | ||||
|     // Initialize tracking  ========================================== | ||||
|  | ||||
|     d_code_loop_filter = Tracking_2nd_DLL_filter(static_cast<float>(d_code_period)); | ||||
|     d_carrier_loop_filter = Tracking_2nd_PLL_filter(static_cast<float>(d_code_period)); | ||||
|     d_carrier_loop_filter.set_PLL_BW(trk_parameters.pll_bw_hz); | ||||
| @@ -264,7 +300,9 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|  | ||||
|     d_correlator_outs = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||
|     d_local_code_shift_chips = static_cast<float *>(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(float), volk_gnsssdr_get_alignment())); | ||||
|     std::fill_n(d_correlator_outs, d_n_correlator_taps, gr_complex(0.0, 0.0)); | ||||
|     //std::fill_n(d_correlator_outs, d_n_correlator_taps, gr_complex(0.0, 0.0)); | ||||
|  | ||||
|     d_code_samples_per_chip = trk_parameters.code_samples_per_chip;  // number of samples per chip | ||||
|  | ||||
|     // map memory pointers of correlator outputs | ||||
|     if (d_veml) | ||||
| @@ -274,6 +312,11 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|             d_Prompt = &d_correlator_outs[2]; | ||||
|             d_Late = &d_correlator_outs[3]; | ||||
|             d_Very_Late = &d_correlator_outs[4]; | ||||
|             //            printf("aaaa very early %f\n",-trk_parameters.very_early_late_space_chips); | ||||
|             //            printf("aaaa early %f\n",-trk_parameters.early_late_space_chips); | ||||
|             //            printf("aaaa normal %f\n",0); | ||||
|             //            printf("aaaa late %f\n",trk_parameters.early_late_space_chips); | ||||
|             //            printf("aaaa very late %f\n",trk_parameters.very_early_late_space_chips); | ||||
|             d_local_code_shift_chips[0] = -trk_parameters.very_early_late_space_chips * static_cast<float>(d_code_samples_per_chip); | ||||
|             d_local_code_shift_chips[1] = -trk_parameters.early_late_space_chips * static_cast<float>(d_code_samples_per_chip); | ||||
|             d_local_code_shift_chips[2] = 0.0; | ||||
| @@ -288,6 +331,10 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|             d_Prompt = &d_correlator_outs[1]; | ||||
|             d_Late = &d_correlator_outs[2]; | ||||
|             d_Very_Late = nullptr; | ||||
|             //            printf("aaaa early %f\n",-trk_parameters.early_late_space_chips); | ||||
|             //            printf("aaaa normal %f\n",0); | ||||
|             //            printf("aaaa late %f\n",trk_parameters.early_late_space_chips); | ||||
|  | ||||
|             d_local_code_shift_chips[0] = -trk_parameters.early_late_space_chips * static_cast<float>(d_code_samples_per_chip); | ||||
|             d_local_code_shift_chips[1] = 0.0; | ||||
|             d_local_code_shift_chips[2] = trk_parameters.early_late_space_chips * static_cast<float>(d_code_samples_per_chip); | ||||
| @@ -308,12 +355,12 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|     if (trk_parameters.track_pilot) | ||||
|         { | ||||
|             // Extra correlator for the data component | ||||
|             d_Prompt_Data = static_cast<gr_complex *>(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||
|             d_Prompt_Data[0] = gr_complex(0.0, 0.0); | ||||
|             //d_Prompt_Data = static_cast<gr_complex *>(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||
|             //d_Prompt_Data[0] = gr_complex(0.0, 0.0); | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             d_Prompt_Data = nullptr; | ||||
|             //d_Prompt_Data = nullptr; | ||||
|         } | ||||
|  | ||||
|     //--- Initializations ---// | ||||
| @@ -327,6 +374,7 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|     // sample synchronization | ||||
|     d_sample_counter = 0; | ||||
|     d_acq_sample_stamp = 0; | ||||
|     d_absolute_samples_offset = 0; | ||||
|  | ||||
|     d_current_prn_length_samples = static_cast<int>(trk_parameters.vector_length); | ||||
|     d_next_prn_length_samples = d_current_prn_length_samples; | ||||
| @@ -339,8 +387,9 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|     d_CN0_SNV_dB_Hz = 0.0; | ||||
|     d_carrier_lock_fail_counter = 0; | ||||
|     d_carrier_lock_threshold = trk_parameters.carrier_lock_th; | ||||
|     d_Prompt_Data = static_cast<gr_complex *>(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||
|  | ||||
|     clear_tracking_vars(); | ||||
|     //clear_tracking_vars(); | ||||
|  | ||||
|     d_acquisition_gnss_synchro = nullptr; | ||||
|     d_channel = 0; | ||||
| @@ -357,23 +406,27 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) | ||||
|     d_code_phase_samples = 0.0; | ||||
|     d_last_prompt = gr_complex(0.0, 0.0); | ||||
|     d_state = 0;  // initial state: standby | ||||
|     clear_tracking_vars(); | ||||
|  | ||||
|     //printf("hhhhhhhhhhh d_n_correlator_taps = %d\n", d_n_correlator_taps); | ||||
|  | ||||
|     // create multicorrelator class | ||||
|     std::string device_name = trk_parameters.device_name; | ||||
|     unsigned int device_base = trk_parameters.device_base; | ||||
|     uint32_t device_base = trk_parameters.device_base; | ||||
|     int *ca_codes = trk_parameters.ca_codes; | ||||
|     unsigned int code_length = trk_parameters.code_length; | ||||
|     multicorrelator_fpga = std::make_shared<fpga_multicorrelator_8sc>(d_n_correlator_taps, device_name, device_base, ca_codes, code_length); | ||||
|     multicorrelator_fpga->set_output_vectors(d_correlator_outs); | ||||
|     int *data_codes = trk_parameters.data_codes; | ||||
|     //uint32_t  code_length = trk_parameters.code_length_chips; | ||||
|     d_code_length_chips = trk_parameters.code_length_chips; | ||||
|     uint32_t multicorr_type = trk_parameters.multicorr_type; | ||||
|     multicorrelator_fpga = std::make_shared<fpga_multicorrelator_8sc>(d_n_correlator_taps, device_name, device_base, ca_codes, data_codes, d_code_length_chips, trk_parameters.track_pilot, multicorr_type, d_code_samples_per_chip); | ||||
|     multicorrelator_fpga->set_output_vectors(d_correlator_outs, d_Prompt_Data); | ||||
|  | ||||
|     d_pull_in = 0; | ||||
| } | ||||
|  | ||||
| void dll_pll_veml_tracking_fpga::start_tracking() | ||||
| { | ||||
|     /* | ||||
|      *  correct the code phase according to the delay between acq and trk | ||||
|      */ | ||||
|     //  correct the code phase according to the delay between acq and trk | ||||
|     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; | ||||
| @@ -381,14 +434,16 @@ void dll_pll_veml_tracking_fpga::start_tracking() | ||||
|     double acq_trk_diff_seconds = 0;  // when using the FPGA we don't use the global sample counter | ||||
|     // Doppler effect Fd = (C / (C + Vr)) * F | ||||
|     double radial_velocity = (d_signal_carrier_freq + d_acq_carrier_doppler_hz) / d_signal_carrier_freq; | ||||
|     // new chip and prn sequence periods based on acq Doppler | ||||
|     // new chip and PRN sequence periods based on acq Doppler | ||||
|     d_code_freq_chips = radial_velocity * d_code_chip_rate; | ||||
|     d_code_phase_step_chips = d_code_freq_chips / trk_parameters.fs_in; | ||||
|  | ||||
|     double T_chip_mod_seconds = 1.0 / d_code_freq_chips; | ||||
|     double T_prn_mod_seconds = T_chip_mod_seconds * static_cast<double>(d_code_length_chips); | ||||
|     double T_prn_mod_samples = T_prn_mod_seconds * trk_parameters.fs_in; | ||||
|  | ||||
|     d_current_prn_length_samples = std::round(T_prn_mod_samples); | ||||
|     //d_current_prn_length_samples = std::round(T_prn_mod_samples); | ||||
|     d_current_prn_length_samples = std::floor(T_prn_mod_samples); | ||||
|     d_next_prn_length_samples = d_current_prn_length_samples; | ||||
|     double T_prn_true_seconds = static_cast<double>(d_code_length_chips) / d_code_chip_rate; | ||||
|     double T_prn_true_samples = T_prn_true_seconds * trk_parameters.fs_in; | ||||
| @@ -433,7 +488,9 @@ void dll_pll_veml_tracking_fpga::start_tracking() | ||||
|         { | ||||
|             if (trk_parameters.track_pilot) | ||||
|                 { | ||||
|                     //char pilot_signal[3] = "1C"; | ||||
|                     d_Prompt_Data[0] = gr_complex(0.0, 0.0); | ||||
|                     // MISSING _: set_local_code_and_taps for the data correlator | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
| @@ -445,7 +502,7 @@ void dll_pll_veml_tracking_fpga::start_tracking() | ||||
|             if (trk_parameters.track_pilot) | ||||
|                 { | ||||
|                     d_secondary_code_string = const_cast<std::string *>(&Galileo_E5a_Q_SECONDARY_CODE[d_acquisition_gnss_synchro->PRN - 1]); | ||||
|                     for (unsigned int i = 0; i < d_code_length_chips; i++) | ||||
|                     for (uint32_t i = 0; i < d_code_length_chips; i++) | ||||
|                         { | ||||
|                             // nothing to compute : the local codes are pre-computed in the adapter class | ||||
|                         } | ||||
| @@ -453,7 +510,7 @@ void dll_pll_veml_tracking_fpga::start_tracking() | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     for (unsigned int i = 0; i < d_code_length_chips; i++) | ||||
|                     for (uint32_t i = 0; i < d_code_length_chips; i++) | ||||
|                         { | ||||
|                             // nothing to compute : the local codes are pre-computed in the adapter class | ||||
|                         } | ||||
| @@ -501,7 +558,8 @@ void dll_pll_veml_tracking_fpga::start_tracking() | ||||
|     LOG(INFO) << "PULL-IN Doppler [Hz] = " << d_carrier_doppler_hz | ||||
|               << ". Code Phase correction [samples] = " << delay_correction_samples | ||||
|               << ". PULL-IN Code Phase [samples] = " << d_acq_code_phase_samples; | ||||
|     multicorrelator_fpga->set_local_code_and_taps(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS), d_local_code_shift_chips, d_acquisition_gnss_synchro->PRN); | ||||
|     //multicorrelator_fpga->set_local_code_and_taps(d_code_length_chips, d_local_code_shift_chips, d_acquisition_gnss_synchro->PRN); | ||||
|     multicorrelator_fpga->set_local_code_and_taps(d_local_code_shift_chips, d_prompt_data_shift, d_acquisition_gnss_synchro->PRN); | ||||
|     d_pull_in = 1; | ||||
|     // enable tracking pull-in and d_state at the end to avoid general work from starting pull-in before the start tracking function is finished | ||||
|     d_state = 1; | ||||
| @@ -509,6 +567,11 @@ void dll_pll_veml_tracking_fpga::start_tracking() | ||||
|  | ||||
| dll_pll_veml_tracking_fpga::~dll_pll_veml_tracking_fpga() | ||||
| { | ||||
|     if (signal_type.compare("1C") == 0) | ||||
|         { | ||||
|             volk_gnsssdr_free(d_gps_l1ca_preambles_symbols); | ||||
|         } | ||||
|  | ||||
|     if (d_dump_file.is_open()) | ||||
|         { | ||||
|             try | ||||
| @@ -536,10 +599,11 @@ dll_pll_veml_tracking_fpga::~dll_pll_veml_tracking_fpga() | ||||
|         { | ||||
|             volk_gnsssdr_free(d_local_code_shift_chips); | ||||
|             volk_gnsssdr_free(d_correlator_outs); | ||||
|             if (trk_parameters.track_pilot) | ||||
|                 { | ||||
|             volk_gnsssdr_free(d_Prompt_Data); | ||||
|                 } | ||||
|             //            if (trk_parameters.track_pilot) | ||||
|             //                { | ||||
|             //                    volk_gnsssdr_free(d_Prompt_Data); | ||||
|             //                } | ||||
|             delete[] d_Prompt_buffer; | ||||
|             multicorrelator_fpga->free(); | ||||
|         } | ||||
| @@ -554,7 +618,7 @@ bool dll_pll_veml_tracking_fpga::acquire_secondary() | ||||
| { | ||||
|     // ******* preamble correlation ******** | ||||
|     int corr_value = 0; | ||||
|     for (unsigned int i = 0; i < d_secondary_code_length; i++) | ||||
|     for (uint32_t i = 0; i < d_secondary_code_length; i++) | ||||
|         { | ||||
|             if (d_Prompt_buffer_deque.at(i).real() < 0.0)  // symbols clipping | ||||
|                 { | ||||
| @@ -580,7 +644,9 @@ bool dll_pll_veml_tracking_fpga::acquire_secondary() | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|     //    if (abs(corr_value) == d_secondary_code_length) | ||||
|     if (abs(corr_value) == static_cast<int>(d_secondary_code_length)) | ||||
|  | ||||
|         { | ||||
|             return true; | ||||
|         } | ||||
| @@ -593,6 +659,7 @@ bool dll_pll_veml_tracking_fpga::acquire_secondary() | ||||
|  | ||||
| bool dll_pll_veml_tracking_fpga::cn0_and_tracking_lock_status(double coh_integration_time_s) | ||||
| { | ||||
|     //printf("kkkkkkkkkkkkk d_cn0_estimation_counter = %d\n", d_cn0_estimation_counter); | ||||
|     // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### | ||||
|     if (d_cn0_estimation_counter < trk_parameters.cn0_samples) | ||||
|         { | ||||
| @@ -603,6 +670,7 @@ bool dll_pll_veml_tracking_fpga::cn0_and_tracking_lock_status(double coh_integra | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             //printf("KKKKKKKKKKK checking count fail ...\n"); | ||||
|             d_cn0_estimation_counter = 0; | ||||
|             // Code lock indicator | ||||
|             d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, trk_parameters.cn0_samples, coh_integration_time_s); | ||||
| @@ -674,7 +742,8 @@ void dll_pll_veml_tracking_fpga::run_dll_pll() | ||||
| void dll_pll_veml_tracking_fpga::clear_tracking_vars() | ||||
| { | ||||
|     std::fill_n(d_correlator_outs, d_n_correlator_taps, gr_complex(0.0, 0.0)); | ||||
|     if (trk_parameters.track_pilot) *d_Prompt_Data = gr_complex(0.0, 0.0); | ||||
|     //if (trk_parameters.track_pilot) *d_Prompt_Data = gr_complex(0.0, 0.0); | ||||
|     if (trk_parameters.track_pilot) d_Prompt_Data[0] = gr_complex(0.0, 0.0); | ||||
|     d_carr_error_hz = 0.0; | ||||
|     d_carr_error_filt_hz = 0.0; | ||||
|     d_code_error_chips = 0.0; | ||||
| @@ -696,7 +765,9 @@ void dll_pll_veml_tracking_fpga::update_tracking_vars() | ||||
|     // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation | ||||
|     T_prn_samples = T_prn_seconds * trk_parameters.fs_in; | ||||
|     K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * trk_parameters.fs_in; | ||||
|     d_next_prn_length_samples = round(K_blk_samples); | ||||
|     //d_next_prn_length_samples = round(K_blk_samples); | ||||
|     d_next_prn_length_samples = static_cast<int>(std::floor(K_blk_samples));  // round to a discrete number of samples | ||||
|  | ||||
|     //################### PLL COMMANDS ################################################# | ||||
|     // carrier phase step (NCO phase increment per sample) [rads/sample] | ||||
|     d_carrier_phase_step_rad = PI_2 * d_carrier_doppler_hz / trk_parameters.fs_in; | ||||
| @@ -712,6 +783,10 @@ void dll_pll_veml_tracking_fpga::update_tracking_vars() | ||||
|     // remnant code phase [chips] | ||||
|     d_rem_code_phase_samples = K_blk_samples - static_cast<double>(d_current_prn_length_samples);  // rounding error < 1 sample | ||||
|     d_rem_code_phase_chips = d_code_freq_chips * d_rem_code_phase_samples / trk_parameters.fs_in; | ||||
|     //printf("lll d_code_freq_chips = %f\n", d_code_freq_chips); | ||||
|     //printf("lll d_rem_code_phase_samples = %f\n", d_rem_code_phase_samples); | ||||
|     //printf("lll trk_parameters.fs_in = %f\n", trk_parameters.fs_in); | ||||
|     //printf("lll d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -776,6 +851,7 @@ void dll_pll_veml_tracking_fpga::log_data(bool integrating) | ||||
|             float tmp_VE, tmp_E, tmp_P, tmp_L, tmp_VL; | ||||
|             float tmp_float; | ||||
|             double tmp_double; | ||||
|             unsigned long int tmp_long_int; | ||||
|             if (trk_parameters.track_pilot) | ||||
|                 { | ||||
|                     if (interchange_iq) | ||||
| @@ -842,7 +918,8 @@ void dll_pll_veml_tracking_fpga::log_data(bool integrating) | ||||
|                     d_dump_file.write(reinterpret_cast<char *>(&prompt_I), sizeof(float)); | ||||
|                     d_dump_file.write(reinterpret_cast<char *>(&prompt_Q), sizeof(float)); | ||||
|                     // PRN start sample stamp | ||||
|                     d_dump_file.write(reinterpret_cast<char *>(&d_sample_counter), sizeof(uint64_t)); | ||||
|                     tmp_long_int = d_sample_counter + static_cast<uint64_t>(d_current_prn_length_samples); | ||||
|                     d_dump_file.write(reinterpret_cast<char *>(&tmp_long_int), sizeof(uint64_t)); | ||||
|                     // accumulated carrier phase | ||||
|                     tmp_float = d_acc_carrier_phase_rad; | ||||
|                     d_dump_file.write(reinterpret_cast<char *>(&tmp_float), sizeof(float)); | ||||
| @@ -872,8 +949,8 @@ void dll_pll_veml_tracking_fpga::log_data(bool integrating) | ||||
|                     tmp_double = static_cast<double>(d_sample_counter + d_current_prn_length_samples); | ||||
|                     d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double)); | ||||
|                     // PRN | ||||
|                     unsigned int prn_ = d_acquisition_gnss_synchro->PRN; | ||||
|                     d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(unsigned int)); | ||||
|                     uint32_t prn_ = d_acquisition_gnss_synchro->PRN; | ||||
|                     d_dump_file.write(reinterpret_cast<char *>(&prn_), sizeof(uint32_t)); | ||||
|                 } | ||||
|             catch (const std::ifstream::failure &e) | ||||
|                 { | ||||
| @@ -890,7 +967,7 @@ int dll_pll_veml_tracking_fpga::save_matfile() | ||||
|     int number_of_double_vars = 1; | ||||
|     int number_of_float_vars = 17; | ||||
|     int epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + | ||||
|                            sizeof(float) * number_of_float_vars + sizeof(unsigned int); | ||||
|                            sizeof(float) * number_of_float_vars + sizeof(uint32_t); | ||||
|     std::ifstream dump_file; | ||||
|     dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); | ||||
|     try | ||||
| @@ -933,7 +1010,7 @@ int dll_pll_veml_tracking_fpga::save_matfile() | ||||
|     float *carrier_lock_test = new float[num_epoch]; | ||||
|     float *aux1 = new float[num_epoch]; | ||||
|     double *aux2 = new double[num_epoch]; | ||||
|     unsigned int *PRN = new unsigned int[num_epoch]; | ||||
|     uint32_t *PRN = new uint32_t[num_epoch]; | ||||
|  | ||||
|     try | ||||
|         { | ||||
| @@ -960,7 +1037,7 @@ int dll_pll_veml_tracking_fpga::save_matfile() | ||||
|                             dump_file.read(reinterpret_cast<char *>(&carrier_lock_test[i]), sizeof(float)); | ||||
|                             dump_file.read(reinterpret_cast<char *>(&aux1[i]), sizeof(float)); | ||||
|                             dump_file.read(reinterpret_cast<char *>(&aux2[i]), sizeof(double)); | ||||
|                             dump_file.read(reinterpret_cast<char *>(&PRN[i]), sizeof(unsigned int)); | ||||
|                             dump_file.read(reinterpret_cast<char *>(&PRN[i]), sizeof(uint32_t)); | ||||
|                         } | ||||
|                 } | ||||
|             dump_file.close(); | ||||
| @@ -1105,7 +1182,7 @@ int dll_pll_veml_tracking_fpga::save_matfile() | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void dll_pll_veml_tracking_fpga::set_channel(unsigned int channel) | ||||
| void dll_pll_veml_tracking_fpga::set_channel(uint32_t channel) | ||||
| { | ||||
|     d_channel = channel; | ||||
|     multicorrelator_fpga->set_channel(d_channel); | ||||
| @@ -1131,21 +1208,14 @@ void dll_pll_veml_tracking_fpga::set_channel(unsigned int channel) | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| void dll_pll_veml_tracking_fpga::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) | ||||
| { | ||||
|     d_acquisition_gnss_synchro = p_gnss_synchro; | ||||
| } | ||||
|  | ||||
|  | ||||
| void dll_pll_veml_tracking_fpga::reset(void) | ||||
| { | ||||
|     multicorrelator_fpga->unlock_channel(); | ||||
| } | ||||
|  | ||||
|  | ||||
| int dll_pll_veml_tracking_fpga::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) | ||||
|     gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) | ||||
| { | ||||
|     // Block input data and block output stream pointers | ||||
|     Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); | ||||
| @@ -1165,7 +1235,7 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un | ||||
|                         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.Tracking_sample_counter = 0;  // in order to reduce computational workload do not read the sample counter until we start tracking d_sample_counter + d_current_prn_length_samples; | ||||
|                 current_synchro_data.System = {'G'}; | ||||
|                 current_synchro_data.correlation_length_ms = 1; | ||||
|                 break; | ||||
| @@ -1174,10 +1244,17 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un | ||||
|             { | ||||
|                 d_pull_in = 0; | ||||
|                 multicorrelator_fpga->lock_channel(); | ||||
|                 unsigned counter_value = multicorrelator_fpga->read_sample_counter(); | ||||
|                 unsigned long long int counter_value = multicorrelator_fpga->read_sample_counter(); | ||||
|                 //printf("333333 counter_value = %llu\n", counter_value); | ||||
|                 //printf("333333 current_synchro_data.Acq_samplestamp_samples = %d\n", current_synchro_data.Acq_samplestamp_samples); | ||||
|                 //printf("333333 current_synchro_data.Acq_delay_samples = %f\n", current_synchro_data.Acq_delay_samples); | ||||
|                 //printf("333333 d_correlation_length_samples = %d\n", d_correlation_length_samples); | ||||
|                 unsigned num_frames = ceil((counter_value - current_synchro_data.Acq_samplestamp_samples - current_synchro_data.Acq_delay_samples) / d_correlation_length_samples); | ||||
|                 unsigned absolute_samples_offset = current_synchro_data.Acq_delay_samples + current_synchro_data.Acq_samplestamp_samples + num_frames * d_correlation_length_samples; | ||||
|                 //printf("333333 num_frames = %d\n", num_frames); | ||||
|                 unsigned long long int absolute_samples_offset = current_synchro_data.Acq_delay_samples + current_synchro_data.Acq_samplestamp_samples + num_frames * d_correlation_length_samples; | ||||
|                 //printf("333333 absolute_samples_offset = %llu\n", absolute_samples_offset); | ||||
|                 multicorrelator_fpga->set_initial_sample(absolute_samples_offset); | ||||
|                 d_absolute_samples_offset = absolute_samples_offset; | ||||
|                 d_sample_counter = absolute_samples_offset; | ||||
|                 current_synchro_data.Tracking_sample_counter = absolute_samples_offset; | ||||
|                 d_sample_counter_next = d_sample_counter; | ||||
| @@ -1195,7 +1272,7 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un | ||||
|                 // perform carrier wipe-off and compute Early, Prompt and Late correlation | ||||
|                 multicorrelator_fpga->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_rem_code_phase_chips * static_cast<float>(d_code_samples_per_chip), d_code_phase_step_chips * static_cast<float>(d_code_samples_per_chip), | ||||
|                     d_current_prn_length_samples); | ||||
|  | ||||
|                 // Save single correlation step variables | ||||
| @@ -1240,33 +1317,70 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un | ||||
|                             } | ||||
|                         else if (d_symbols_per_bit > 1)  //Signal does not have secondary code. Search a bit transition by sign change | ||||
|                             { | ||||
|                                 if (d_synchonizing) | ||||
|                                 //                                if (d_synchonizing) | ||||
|                                 //                                    { | ||||
|                                 //                                        if (d_Prompt->real() * d_last_prompt.real() > 0.0) | ||||
|                                 //                                            { | ||||
|                                 //                                                d_current_symbol++; | ||||
|                                 //                                            } | ||||
|                                 //                                        else if (d_current_symbol > d_symbols_per_bit) | ||||
|                                 //                                            { | ||||
|                                 //                                                d_synchonizing = false; | ||||
|                                 //                                                d_current_symbol = 1; | ||||
|                                 //                                            } | ||||
|                                 //                                        else | ||||
|                                 //                                            { | ||||
|                                 //                                                d_current_symbol = 1; | ||||
|                                 //                                                d_last_prompt = *d_Prompt; | ||||
|                                 //                                            } | ||||
|                                 //                                    } | ||||
|                                 //                                else if (d_last_prompt.real() != 0.0) | ||||
|                                 //                                    { | ||||
|                                 //                                        d_current_symbol++; | ||||
|                                 //                                        if (d_current_symbol == d_symbols_per_bit) next_state = true; | ||||
|                                 //                                    } | ||||
|                                 //                                else | ||||
|                                 //                                    { | ||||
|                                 //                                        d_last_prompt = *d_Prompt; | ||||
|                                 //                                        d_synchonizing = true; | ||||
|                                 //                                        d_current_symbol = 1; | ||||
|                                 //                                    } | ||||
|                                 //                            } | ||||
|                                 //=========================================================================================================== | ||||
|                                 //float current_tracking_time_s = static_cast<float>(d_sample_counter - d_acq_sample_stamp) / trk_parameters.fs_in; | ||||
|                                 float current_tracking_time_s = static_cast<float>(d_sample_counter - d_absolute_samples_offset) / trk_parameters.fs_in; | ||||
|                                 if (current_tracking_time_s > 10) | ||||
|                                     { | ||||
|                                         if (d_Prompt->real() * d_last_prompt.real() > 0.0) | ||||
|                                         d_symbol_history.push_back(d_Prompt->real()); | ||||
|                                         //******* preamble correlation ******** | ||||
|                                         int corr_value = 0; | ||||
|                                         if ((d_symbol_history.size() == GPS_CA_PREAMBLE_LENGTH_SYMBOLS))  // and (d_make_correlation or !d_flag_frame_sync)) | ||||
|                                             { | ||||
|                                                 d_current_symbol++; | ||||
|                                             } | ||||
|                                         else if (d_current_symbol > d_symbols_per_bit) | ||||
|                                                 for (uint32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++) | ||||
|                                                     { | ||||
|                                                 d_synchonizing = false; | ||||
|                                                 d_current_symbol = 1; | ||||
|                                                         if (d_symbol_history.at(i) < 0)  // symbols clipping | ||||
|                                                             { | ||||
|                                                                 corr_value -= d_gps_l1ca_preambles_symbols[i]; | ||||
|                                                             } | ||||
|                                                         else | ||||
|                                                             { | ||||
|                                                 d_current_symbol = 1; | ||||
|                                                 d_last_prompt = *d_Prompt; | ||||
|                                                                 corr_value += d_gps_l1ca_preambles_symbols[i]; | ||||
|                                                             } | ||||
|                                                     } | ||||
|                                 else if (d_last_prompt.real() != 0.0) | ||||
|                                             } | ||||
|                                         if (corr_value == GPS_CA_PREAMBLE_LENGTH_SYMBOLS) | ||||
|                                             { | ||||
|                                         d_current_symbol++; | ||||
|                                         if (d_current_symbol == d_symbols_per_bit) next_state = true; | ||||
|                                                 //std::cout << "Preamble detected at tracking!" << std::endl; | ||||
|                                                 next_state = true; | ||||
|                                             } | ||||
|                                         else | ||||
|                                             { | ||||
|                                         d_last_prompt = *d_Prompt; | ||||
|                                         d_synchonizing = true; | ||||
|                                         d_current_symbol = 1; | ||||
|                                                 next_state = false; | ||||
|                                             } | ||||
|                                     } | ||||
|                                 else | ||||
|                                     { | ||||
|                                         next_state = false; | ||||
|                                     } | ||||
|                             } | ||||
|                         else | ||||
| @@ -1274,6 +1388,43 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un | ||||
|                                 next_state = true; | ||||
|                             } | ||||
|  | ||||
|                         // ########### Output the tracking results to Telemetry block ########## | ||||
|                         if (interchange_iq) | ||||
|                             { | ||||
|                                 if (trk_parameters.track_pilot) | ||||
|                                     { | ||||
|                                         // Note that data and pilot components are in quadrature. I and Q are interchanged | ||||
|                                         current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).imag()); | ||||
|                                         current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).real()); | ||||
|                                     } | ||||
|                                 else | ||||
|                                     { | ||||
|                                         current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).imag()); | ||||
|                                         current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).real()); | ||||
|                                     } | ||||
|                             } | ||||
|                         else | ||||
|                             { | ||||
|                                 if (trk_parameters.track_pilot) | ||||
|                                     { | ||||
|                                         // Note that data and pilot components are in quadrature. I and Q are interchanged | ||||
|                                         current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).real()); | ||||
|                                         current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).imag()); | ||||
|                                     } | ||||
|                                 else | ||||
|                                     { | ||||
|                                         current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).real()); | ||||
|                                         current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).imag()); | ||||
|                                     } | ||||
|                             } | ||||
|                         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 = d_correlation_length_ms; | ||||
|  | ||||
|  | ||||
|                         if (next_state) | ||||
|                             {  // reset extended correlator | ||||
|                                 d_VE_accu = gr_complex(0.0, 0.0); | ||||
| @@ -1336,7 +1487,7 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un | ||||
|                 // perform a correlation step | ||||
|                 multicorrelator_fpga->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_rem_code_phase_chips * static_cast<float>(d_code_samples_per_chip), d_code_phase_step_chips * static_cast<float>(d_code_samples_per_chip), | ||||
|                     d_current_prn_length_samples); | ||||
|                 update_tracking_vars(); | ||||
|                 save_correlation_results(); | ||||
| @@ -1395,7 +1546,7 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un | ||||
|                 //do_correlation_step(in); | ||||
|                 multicorrelator_fpga->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_rem_code_phase_chips * static_cast<float>(d_code_samples_per_chip), d_code_phase_step_chips * static_cast<float>(d_code_samples_per_chip), | ||||
|                     d_current_prn_length_samples); | ||||
|  | ||||
|                 save_correlation_results(); | ||||
| @@ -1471,3 +1622,8 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un | ||||
|         } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void dll_pll_veml_tracking_fpga::reset(void) | ||||
| { | ||||
|     multicorrelator_fpga->unlock_channel(); | ||||
| } | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (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,7 +31,7 @@ | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
| @@ -39,51 +39,58 @@ | ||||
| #ifndef GNSS_SDR_DLL_PLL_VEML_TRACKING_FPGA_H | ||||
| #define GNSS_SDR_DLL_PLL_VEML_TRACKING_FPGA_H | ||||
|  | ||||
| #include "fpga_multicorrelator.h" | ||||
| #include "dll_pll_conf_fpga.h" | ||||
| #include "gnss_synchro.h" | ||||
| #include "tracking_2nd_DLL_filter.h" | ||||
| #include "tracking_2nd_PLL_filter.h" | ||||
| #include "fpga_multicorrelator.h" | ||||
| #include <gnuradio/block.h> | ||||
| #include <fstream> | ||||
| #include <string> | ||||
| #include <map> | ||||
| #include <queue> | ||||
| #include <boost/circular_buffer.hpp> | ||||
| #include "fpga_multicorrelator.h" | ||||
|  | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|     /* DLL/PLL tracking configuration */ | ||||
|     double fs_in; | ||||
|     unsigned int vector_length; | ||||
|     bool dump; | ||||
|     std::string dump_filename; | ||||
|     float pll_bw_hz; | ||||
|     float dll_bw_hz; | ||||
|     float pll_bw_narrow_hz; | ||||
|     float dll_bw_narrow_hz; | ||||
|     float early_late_space_chips; | ||||
|     float very_early_late_space_chips; | ||||
|     float early_late_space_narrow_chips; | ||||
|     float very_early_late_space_narrow_chips; | ||||
|     int extend_correlation_symbols; | ||||
|     int cn0_samples; | ||||
|     int cn0_min; | ||||
|     int max_lock_fail; | ||||
|     double carrier_lock_th; | ||||
|     bool track_pilot; | ||||
|     char system; | ||||
|     char signal[3]; | ||||
|     std::string device_name; | ||||
|     unsigned int device_base; | ||||
|     unsigned int code_length; | ||||
|     int *ca_codes; | ||||
| } dllpllconf_fpga_t; | ||||
| //typedef struct | ||||
| //{ | ||||
| //    /* DLL/PLL tracking configuration */ | ||||
| //    double fs_in; | ||||
| //    uint32_t  vector_length; | ||||
| //    bool dump; | ||||
| //    std::string dump_filename; | ||||
| //    float pll_bw_hz; | ||||
| //    float dll_bw_hz; | ||||
| //    float pll_bw_narrow_hz; | ||||
| //    float dll_bw_narrow_hz; | ||||
| //    float early_late_space_chips; | ||||
| //    float very_early_late_space_chips; | ||||
| //    float early_late_space_narrow_chips; | ||||
| //    float very_early_late_space_narrow_chips; | ||||
| //    int32_t extend_correlation_symbols; | ||||
| //    int32_t cn0_samples; | ||||
| //    int32_t cn0_min; | ||||
| //    int32_t max_lock_fail; | ||||
| //    double carrier_lock_th; | ||||
| //    bool track_pilot; | ||||
| //    char system; | ||||
| //    char signal[3]; | ||||
| //    std::string device_name; | ||||
| //    uint32_t  device_base; | ||||
| //    uint32_t  multicorr_type; | ||||
| //    uint32_t  code_length_chips; | ||||
| //    uint32_t  code_samples_per_chip; | ||||
| //    int* ca_codes; | ||||
| //    int* data_codes; | ||||
| //} dllpllconf_fpga_t; | ||||
|  | ||||
| class dll_pll_veml_tracking_fpga; | ||||
|  | ||||
| typedef boost::shared_ptr<dll_pll_veml_tracking_fpga> | ||||
|     dll_pll_veml_tracking_fpga_sptr; | ||||
|  | ||||
| dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(dllpllconf_fpga_t conf_); | ||||
| //dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const dllpllconf_fpga_t &conf_); | ||||
| dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_); | ||||
|  | ||||
|  | ||||
| /*! | ||||
| @@ -94,7 +101,7 @@ class dll_pll_veml_tracking_fpga : public gr::block | ||||
| public: | ||||
|     ~dll_pll_veml_tracking_fpga(); | ||||
|  | ||||
|     void set_channel(unsigned int channel); | ||||
|     void set_channel(uint32_t channel); | ||||
|     void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro); | ||||
|     void start_tracking(); | ||||
|  | ||||
| @@ -104,9 +111,10 @@ public: | ||||
|     void reset(void); | ||||
|  | ||||
| private: | ||||
|     friend dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(dllpllconf_fpga_t conf_); | ||||
|     friend dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_); | ||||
|  | ||||
|     dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_); | ||||
|     dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_); | ||||
|     void msg_handler_preamble_index(pmt::pmt_t msg); | ||||
|  | ||||
|     bool cn0_and_tracking_lock_status(double coh_integration_time_s); | ||||
|     bool acquire_secondary(); | ||||
| @@ -115,13 +123,14 @@ private: | ||||
|     void clear_tracking_vars(); | ||||
|     void save_correlation_results(); | ||||
|     void log_data(bool integrating); | ||||
|     int save_matfile(); | ||||
|     int32_t save_matfile(); | ||||
|  | ||||
|     // tracking configuration vars | ||||
|     dllpllconf_fpga_t trk_parameters; | ||||
|     Dll_Pll_Conf_Fpga trk_parameters; | ||||
|     //dllpllconf_fpga_t trk_parameters; | ||||
|     bool d_veml; | ||||
|     bool d_cloop; | ||||
|     unsigned int d_channel; | ||||
|     uint32_t d_channel; | ||||
|     Gnss_Synchro *d_acquisition_gnss_synchro; | ||||
|  | ||||
|     //Signal parameters | ||||
| @@ -130,21 +139,24 @@ private: | ||||
|     double d_signal_carrier_freq; | ||||
|     double d_code_period; | ||||
|     double d_code_chip_rate; | ||||
|     unsigned int d_secondary_code_length; | ||||
|     unsigned int d_code_length_chips; | ||||
|     unsigned int d_code_samples_per_chip;  // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled) | ||||
|     int d_symbols_per_bit; | ||||
|     uint32_t d_secondary_code_length; | ||||
|     uint32_t d_code_length_chips; | ||||
|     uint32_t d_code_samples_per_chip;  // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled) | ||||
|     int32_t d_symbols_per_bit; | ||||
|     std::string systemName; | ||||
|     std::string signal_type; | ||||
|     std::string *d_secondary_code_string; | ||||
|     std::string signal_pretty_name; | ||||
|  | ||||
|     int32_t *d_gps_l1ca_preambles_symbols; | ||||
|     boost::circular_buffer<float> d_symbol_history; | ||||
|  | ||||
|     //tracking state machine | ||||
|     int d_state; | ||||
|     int32_t d_state; | ||||
|     bool d_synchonizing; | ||||
|     //Integration period in samples | ||||
|     int d_correlation_length_ms; | ||||
|     int d_n_correlator_taps; | ||||
|     int32_t d_correlation_length_ms; | ||||
|     int32_t d_n_correlator_taps; | ||||
|     float *d_local_code_shift_chips; | ||||
|     float *d_prompt_data_shift; | ||||
|     std::shared_ptr<fpga_multicorrelator_8sc> multicorrelator_fpga; | ||||
| @@ -157,8 +169,8 @@ private: | ||||
|     gr_complex *d_Very_Late; | ||||
|  | ||||
|     bool d_enable_extended_integration; | ||||
|     int d_extend_correlation_symbols_count; | ||||
|     int d_current_symbol; | ||||
|     int32_t d_extend_correlation_symbols_count; | ||||
|     int32_t d_current_symbol; | ||||
|  | ||||
|     gr_complex d_VE_accu; | ||||
|     gr_complex d_E_accu; | ||||
| @@ -199,14 +211,15 @@ private: | ||||
|     double T_prn_samples; | ||||
|     double K_blk_samples; | ||||
|     // PRN period in samples | ||||
|     int d_current_prn_length_samples; | ||||
|     int32_t d_current_prn_length_samples; | ||||
|     // processing samples counters | ||||
|     uint64_t d_sample_counter; | ||||
|     uint64_t d_acq_sample_stamp; | ||||
|     uint64_t d_absolute_samples_offset; | ||||
|  | ||||
|     // CN0 estimation and lock detector | ||||
|     int d_cn0_estimation_counter; | ||||
|     int d_carrier_lock_fail_counter; | ||||
|     int32_t d_cn0_estimation_counter; | ||||
|     int32_t d_carrier_lock_fail_counter; | ||||
|     double d_carrier_lock_test; | ||||
|     double d_CN0_SNV_dB_Hz; | ||||
|     double d_carrier_lock_threshold; | ||||
| @@ -217,10 +230,10 @@ private: | ||||
|     std::ofstream d_dump_file; | ||||
|  | ||||
|     // extra | ||||
|     int d_correlation_length_samples; | ||||
|     int d_next_prn_length_samples; | ||||
|     int32_t d_correlation_length_samples; | ||||
|     int32_t d_next_prn_length_samples; | ||||
|     uint64_t d_sample_counter_next; | ||||
|     unsigned int d_pull_in = 0; | ||||
|     uint32_t d_pull_in = 0; | ||||
| }; | ||||
|  | ||||
| #endif  //GNSS_SDR_DLL_PLL_VEML_TRACKING_FPGA_H | ||||
|   | ||||
| @@ -47,7 +47,7 @@ set(TRACKING_LIB_SOURCES | ||||
| ) | ||||
|  | ||||
| if(ENABLE_FPGA) | ||||
|     SET(TRACKING_LIB_SOURCES ${TRACKING_LIB_SOURCES} fpga_multicorrelator.cc) | ||||
|     SET(TRACKING_LIB_SOURCES ${TRACKING_LIB_SOURCES} fpga_multicorrelator.cc dll_pll_conf_fpga.cc) | ||||
| endif(ENABLE_FPGA) | ||||
|  | ||||
| include_directories( | ||||
|   | ||||
							
								
								
									
										91
									
								
								src/algorithms/tracking/libs/dll_pll_conf_fpga.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/algorithms/tracking/libs/dll_pll_conf_fpga.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| /*! | ||||
|  * \file dll_pll_conf.cc | ||||
|  * \brief Class that contains all the configuration parameters for generic | ||||
|  * tracking block based on a DLL and a PLL. | ||||
|  * \author Javier Arribas, 2018. jarribas(at)cttc.es | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include "dll_pll_conf_fpga.h" | ||||
| #include <cstring> | ||||
|  | ||||
| Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga() | ||||
| { | ||||
|     //    /* DLL/PLL tracking configuration */ | ||||
|     //    fs_in = 0.0; | ||||
|     //    vector_length = 0; | ||||
|     //    dump = false; | ||||
|     //    dump_filename = "./dll_pll_dump.dat"; | ||||
|     //    pll_bw_hz = 40.0; | ||||
|     //    dll_bw_hz = 2.0; | ||||
|     //    pll_bw_narrow_hz = 5.0; | ||||
|     //    dll_bw_narrow_hz = 0.75; | ||||
|     //    early_late_space_chips = 0.5; | ||||
|     //    very_early_late_space_chips = 0.5; | ||||
|     //    early_late_space_narrow_chips = 0.1; | ||||
|     //    very_early_late_space_narrow_chips = 0.1; | ||||
|     //    extend_correlation_symbols = 5; | ||||
|     //    cn0_samples = 20; | ||||
|     //    carrier_lock_det_mav_samples = 20; | ||||
|     //    cn0_min = 25; | ||||
|     //    max_lock_fail = 50; | ||||
|     //    carrier_lock_th = 0.85; | ||||
|     //    track_pilot = false; | ||||
|     //    system = 'G'; | ||||
|     //    char sig_[3] = "1C"; | ||||
|     //    std::memcpy(signal, sig_, 3); | ||||
|  | ||||
|     /* DLL/PLL tracking configuration */ | ||||
|     fs_in = 0.0; | ||||
|     vector_length = 0; | ||||
|     dump = false; | ||||
|     dump_filename = "./dll_pll_dump.dat"; | ||||
|     pll_bw_hz = 40.0; | ||||
|     dll_bw_hz = 2.0; | ||||
|     pll_bw_narrow_hz = 5.0; | ||||
|     dll_bw_narrow_hz = 0.75; | ||||
|     early_late_space_chips = 0.5; | ||||
|     very_early_late_space_chips = 0.5; | ||||
|     early_late_space_narrow_chips = 0.1; | ||||
|     very_early_late_space_narrow_chips = 0.1; | ||||
|     extend_correlation_symbols = 5; | ||||
|     cn0_samples = 20; | ||||
|     cn0_min = 25; | ||||
|     max_lock_fail = 50; | ||||
|     carrier_lock_th = 0.85; | ||||
|     track_pilot = false; | ||||
|     system = 'G'; | ||||
|     char sig_[3] = "1C"; | ||||
|     std::memcpy(signal, sig_, 3); | ||||
|     device_name = "/dev/uio"; | ||||
|     device_base = 1; | ||||
|     multicorr_type = 0; | ||||
|     code_length_chips = 0; | ||||
|     code_samples_per_chip = 0; | ||||
|     //int32_t* ca_codes; | ||||
|     //int32_t* data_codes; | ||||
| } | ||||
							
								
								
									
										98
									
								
								src/algorithms/tracking/libs/dll_pll_conf_fpga.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								src/algorithms/tracking/libs/dll_pll_conf_fpga.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| /*! | ||||
|  * \file dll_pll_conf.h | ||||
|  * \brief Class that contains all the configuration parameters for generic tracking block based on a DLL and a PLL. | ||||
|  * \author Javier Arribas, 2018. jarribas(at)cttc.es | ||||
|  * | ||||
|  * Class that contains all the configuration parameters for generic tracking block based on a DLL and a PLL. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_DLL_PLL_CONF_FPGA_H_ | ||||
| #define GNSS_SDR_DLL_PLL_CONF_FPGA_H_ | ||||
|  | ||||
| #include <cstdint> | ||||
| #include <string> | ||||
|  | ||||
| class Dll_Pll_Conf_Fpga | ||||
| { | ||||
| private: | ||||
| public: | ||||
|     //    /* DLL/PLL tracking configuration */ | ||||
|     //    double fs_in; | ||||
|     //    uint32_t  vector_length; | ||||
|     //    bool dump; | ||||
|     //    std::string dump_filename; | ||||
|     //    float pll_bw_hz; | ||||
|     //    float dll_bw_hz; | ||||
|     //    float pll_bw_narrow_hz; | ||||
|     //    float dll_bw_narrow_hz; | ||||
|     //    float early_late_space_chips; | ||||
|     //    float very_early_late_space_chips; | ||||
|     //    float early_late_space_narrow_chips; | ||||
|     //    float very_early_late_space_narrow_chips; | ||||
|     //    int32_t extend_correlation_symbols; | ||||
|     //    int32_t cn0_samples; | ||||
|     //    int32_t carrier_lock_det_mav_samples; | ||||
|     //    int32_t cn0_min; | ||||
|     //    int32_t max_lock_fail; | ||||
|     //    double carrier_lock_th; | ||||
|     //    bool track_pilot; | ||||
|     //    char system; | ||||
|     //    char signal[3]; | ||||
|  | ||||
|     /* DLL/PLL tracking configuration */ | ||||
|     double fs_in; | ||||
|     uint32_t vector_length; | ||||
|     bool dump; | ||||
|     std::string dump_filename; | ||||
|     float pll_bw_hz; | ||||
|     float dll_bw_hz; | ||||
|     float pll_bw_narrow_hz; | ||||
|     float dll_bw_narrow_hz; | ||||
|     float early_late_space_chips; | ||||
|     float very_early_late_space_chips; | ||||
|     float early_late_space_narrow_chips; | ||||
|     float very_early_late_space_narrow_chips; | ||||
|     int32_t extend_correlation_symbols; | ||||
|     int32_t cn0_samples; | ||||
|     int32_t cn0_min; | ||||
|     int32_t max_lock_fail; | ||||
|     double carrier_lock_th; | ||||
|     bool track_pilot; | ||||
|     char system; | ||||
|     char signal[3]; | ||||
|     std::string device_name; | ||||
|     uint32_t device_base; | ||||
|     uint32_t multicorr_type; | ||||
|     uint32_t code_length_chips; | ||||
|     uint32_t code_samples_per_chip; | ||||
|     int32_t* ca_codes; | ||||
|     int32_t* data_codes; | ||||
|  | ||||
|     Dll_Pll_Conf_Fpga(); | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| @@ -84,34 +84,46 @@ | ||||
| #define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000 | ||||
| #define TEST_REGISTER_TRACK_WRITEVAL 0x55AA | ||||
|  | ||||
| int fpga_multicorrelator_8sc::read_sample_counter() | ||||
| uint64_t fpga_multicorrelator_8sc::read_sample_counter() | ||||
| { | ||||
| 	return d_map_base[7]; | ||||
|     uint64_t sample_counter_tmp, sample_counter_msw_tmp; | ||||
|     sample_counter_tmp = d_map_base[d_SAMPLE_COUNTER_REG_ADDR_LSW]; | ||||
|     sample_counter_msw_tmp = d_map_base[d_SAMPLE_COUNTER_REG_ADDR_MSW]; | ||||
|     sample_counter_msw_tmp = sample_counter_msw_tmp << 32; | ||||
|     sample_counter_tmp = sample_counter_tmp + sample_counter_msw_tmp;  // 2^32 | ||||
|     //return d_map_base[d_SAMPLE_COUNTER_REG_ADDR]; | ||||
|     return sample_counter_tmp; | ||||
| } | ||||
|  | ||||
| void fpga_multicorrelator_8sc::set_initial_sample(int samples_offset) | ||||
| void fpga_multicorrelator_8sc::set_initial_sample(uint64_t samples_offset) | ||||
| { | ||||
|     d_initial_sample_counter = samples_offset; | ||||
|     d_map_base[13] = d_initial_sample_counter; | ||||
|     //printf("www writing d map base %d = d_initial_sample_counter = %d\n", d_INITIAL_COUNTER_VALUE_REG_ADDR, d_initial_sample_counter); | ||||
|     d_map_base[d_INITIAL_COUNTER_VALUE_REG_ADDR_LSW] = (d_initial_sample_counter & 0xFFFFFFFF); | ||||
|     d_map_base[d_INITIAL_COUNTER_VALUE_REG_ADDR_MSW] = (d_initial_sample_counter >> 32) & 0xFFFFFFFF; | ||||
| } | ||||
|  | ||||
| void fpga_multicorrelator_8sc::set_local_code_and_taps(int code_length_chips, | ||||
|         float *shifts_chips, int PRN)              | ||||
| { | ||||
| //void fpga_multicorrelator_8sc::set_local_code_and_taps(int32_t code_length_chips, | ||||
| //        float *shifts_chips, int32_t PRN) | ||||
|  | ||||
| void fpga_multicorrelator_8sc::set_local_code_and_taps(float *shifts_chips, float *prompt_data_shift, int32_t PRN) | ||||
| { | ||||
|     d_shifts_chips = shifts_chips; | ||||
|     d_code_length_chips = code_length_chips; | ||||
|     d_prompt_data_shift = prompt_data_shift; | ||||
|     //d_code_length_chips = code_length_chips; | ||||
|     fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(PRN); | ||||
| } | ||||
|  | ||||
| void fpga_multicorrelator_8sc::set_output_vectors(gr_complex* corr_out) | ||||
| void fpga_multicorrelator_8sc::set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data) | ||||
| { | ||||
|     d_corr_out = corr_out; | ||||
|     d_Prompt_Data = Prompt_Data; | ||||
| } | ||||
|  | ||||
| void fpga_multicorrelator_8sc::update_local_code(float rem_code_phase_chips) | ||||
| { | ||||
|     d_rem_code_phase_chips = rem_code_phase_chips; | ||||
|     //printf("uuuuu d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips); | ||||
|     fpga_multicorrelator_8sc::fpga_compute_code_shift_parameters(); | ||||
|     fpga_multicorrelator_8sc::fpga_configure_code_parameters_in_fpga(); | ||||
| } | ||||
| @@ -120,10 +132,8 @@ void fpga_multicorrelator_8sc::update_local_code(float rem_code_phase_chips) | ||||
| void fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler( | ||||
|     float rem_carrier_phase_in_rad, float phase_step_rad, | ||||
|     float rem_code_phase_chips, float code_phase_step_chips, | ||||
|         int signal_length_samples) | ||||
|     int32_t signal_length_samples) | ||||
| { | ||||
|  | ||||
|  | ||||
|     update_local_code(rem_code_phase_chips); | ||||
|     d_rem_carrier_phase_in_rad = rem_carrier_phase_in_rad; | ||||
|     d_code_phase_step_chips = code_phase_step_chips; | ||||
| @@ -132,9 +142,11 @@ void fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler( | ||||
|     fpga_multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(); | ||||
|     fpga_multicorrelator_8sc::fpga_configure_signal_parameters_in_fpga(); | ||||
|     fpga_multicorrelator_8sc::fpga_launch_multicorrelator_fpga(); | ||||
|     int irq_count; | ||||
|     int32_t irq_count; | ||||
|     ssize_t nb; | ||||
|     //printf("$$$$$ waiting for interrupt ... \n"); | ||||
|     nb = read(d_device_descriptor, &irq_count, sizeof(irq_count)); | ||||
|     //printf("$$$$$ interrupt received ... \n"); | ||||
|     if (nb != sizeof(irq_count)) | ||||
|         { | ||||
|             printf("Tracking_module Read failed to retrieve 4 bytes!\n"); | ||||
| @@ -143,23 +155,35 @@ void fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler( | ||||
|     fpga_multicorrelator_8sc::read_tracking_gps_results(); | ||||
| } | ||||
|  | ||||
| fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int n_correlators, | ||||
|         std::string device_name, unsigned int device_base, int *ca_codes, unsigned int code_length) | ||||
| fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int32_t n_correlators, | ||||
|     std::string device_name, uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, | ||||
|     uint32_t multicorr_type, uint32_t code_samples_per_chip) | ||||
| { | ||||
|     //printf("tracking fpga class created\n"); | ||||
|     d_n_correlators = n_correlators; | ||||
|     d_device_name = device_name; | ||||
|     d_device_base = device_base; | ||||
|     d_track_pilot = track_pilot; | ||||
|     d_device_descriptor = 0; | ||||
|     d_map_base = nullptr; | ||||
|  | ||||
|     // instantiate variable length vectors | ||||
|     d_initial_index = static_cast<unsigned*>(volk_gnsssdr_malloc( | ||||
|             n_correlators * sizeof(unsigned), volk_gnsssdr_get_alignment())); | ||||
|     d_initial_interp_counter = static_cast<unsigned*>(volk_gnsssdr_malloc( | ||||
|             n_correlators * sizeof(unsigned), volk_gnsssdr_get_alignment())); | ||||
|  | ||||
|     //d_local_code_in = nullptr; | ||||
|     if (d_track_pilot) | ||||
|         { | ||||
|             d_initial_index = static_cast<uint32_t *>(volk_gnsssdr_malloc( | ||||
|                 (n_correlators + 1) * sizeof(uint32_t), volk_gnsssdr_get_alignment())); | ||||
|             d_initial_interp_counter = static_cast<uint32_t *>(volk_gnsssdr_malloc( | ||||
|                 (n_correlators + 1) * sizeof(uint32_t), volk_gnsssdr_get_alignment())); | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             d_initial_index = static_cast<uint32_t *>(volk_gnsssdr_malloc( | ||||
|                 n_correlators * sizeof(uint32_t), volk_gnsssdr_get_alignment())); | ||||
|             d_initial_interp_counter = static_cast<uint32_t *>(volk_gnsssdr_malloc( | ||||
|                 n_correlators * sizeof(uint32_t), volk_gnsssdr_get_alignment())); | ||||
|         } | ||||
|     d_shifts_chips = nullptr; | ||||
|     d_prompt_data_shift = nullptr; | ||||
|     d_corr_out = nullptr; | ||||
|     d_code_length_chips = 0; | ||||
|     d_rem_code_phase_chips = 0; | ||||
| @@ -171,23 +195,103 @@ fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int n_correlators, | ||||
|     d_initial_sample_counter = 0; | ||||
|     d_channel = 0; | ||||
|     d_correlator_length_samples = 0, | ||||
|     d_code_length = code_length; | ||||
|      | ||||
|     // pre-compute all the codes | ||||
| //    d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(GPS_L1_CA_CODE_LENGTH_CHIPS*NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); | ||||
| //    for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) | ||||
| //    { | ||||
| //		gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0); | ||||
| //    } | ||||
|     //d_code_length = code_length; | ||||
|         d_code_length_chips = code_length_chips; | ||||
|     d_ca_codes = ca_codes; | ||||
|     DLOG(INFO) << "TRACKING FPGA CLASS CREATED"; | ||||
|     d_data_codes = data_codes; | ||||
|     d_multicorr_type = multicorr_type; | ||||
|  | ||||
|     d_code_samples_per_chip = code_samples_per_chip; | ||||
|     // set up register mapping | ||||
|  | ||||
|     // write-only registers | ||||
|     d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR = 0; | ||||
|     d_INITIAL_INDEX_REG_BASE_ADDR = 1; | ||||
|     //    if (d_multicorr_type == 0) | ||||
|     //        { | ||||
|     //            // multicorrelator with 3 correlators (16 registers only) | ||||
|     //            d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR = 4; | ||||
|     //            d_NSAMPLES_MINUS_1_REG_ADDR = 7; | ||||
|     //            d_CODE_LENGTH_MINUS_1_REG_ADDR = 8; | ||||
|     //            d_REM_CARR_PHASE_RAD_REG_ADDR = 9; | ||||
|     //            d_PHASE_STEP_RAD_REG_ADDR = 10; | ||||
|     //            d_PROG_MEMS_ADDR = 11; | ||||
|     //            d_DROP_SAMPLES_REG_ADDR = 12; | ||||
|     //            d_INITIAL_COUNTER_VALUE_REG_ADDR = 13; | ||||
|     //            d_START_FLAG_ADDR = 14; | ||||
|     //        } | ||||
|     //    else | ||||
|     //        { | ||||
|     // other types of multicorrelators (32 registers) | ||||
|     d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR = 7; | ||||
|     d_NSAMPLES_MINUS_1_REG_ADDR = 13; | ||||
|     d_CODE_LENGTH_MINUS_1_REG_ADDR = 14; | ||||
|     d_REM_CARR_PHASE_RAD_REG_ADDR = 15; | ||||
|     d_PHASE_STEP_RAD_REG_ADDR = 16; | ||||
|     d_PROG_MEMS_ADDR = 17; | ||||
|     d_DROP_SAMPLES_REG_ADDR = 18; | ||||
|     d_INITIAL_COUNTER_VALUE_REG_ADDR_LSW = 19; | ||||
|     d_INITIAL_COUNTER_VALUE_REG_ADDR_MSW = 20; | ||||
|     d_START_FLAG_ADDR = 30; | ||||
|     //        } | ||||
|  | ||||
|     //printf("d_n_correlators = %d\n", d_n_correlators); | ||||
|     //printf("d_multicorr_type = %d\n", d_multicorr_type); | ||||
|     // read-write registers | ||||
|     //    if (d_multicorr_type == 0) | ||||
|     //        { | ||||
|     //            // multicorrelator with 3 correlators (16 registers only) | ||||
|     //            d_TEST_REG_ADDR = 15; | ||||
|     //        } | ||||
|     //    else | ||||
|     //        { | ||||
|     // other types of multicorrelators (32 registers) | ||||
|     d_TEST_REG_ADDR = 31; | ||||
|     //       } | ||||
|  | ||||
|     // result 2's complement saturation value | ||||
|     //    if (d_multicorr_type == 0) | ||||
|     //        { | ||||
|     //            // multicorrelator with 3 correlators (16 registers only) | ||||
|     //            d_result_SAT_value = 1048576; // 21 bits 2's complement -> 2^20 | ||||
|     //        } | ||||
|     //    else | ||||
|     //        { | ||||
|     //            // other types of multicorrelators (32 registers) | ||||
|     //            d_result_SAT_value = 4194304; // 23 bits 2's complement -> 2^22 | ||||
|     //        } | ||||
|  | ||||
|     // read only registers | ||||
|     d_RESULT_REG_REAL_BASE_ADDR = 1; | ||||
|     //    if (d_multicorr_type == 0) | ||||
|     //        { | ||||
|     //            // multicorrelator with 3 correlators (16 registers only) | ||||
|     //            d_RESULT_REG_IMAG_BASE_ADDR = 4; | ||||
|     //            d_RESULT_REG_DATA_REAL_BASE_ADDR = 0; // no pilot tracking | ||||
|     //            d_RESULT_REG_DATA_IMAG_BASE_ADDR = 0; | ||||
|     //            d_SAMPLE_COUNTER_REG_ADDR = 7; | ||||
|     // | ||||
|     //        } | ||||
|     //    else | ||||
|     //        { | ||||
|     // other types of multicorrelators (32 registers) | ||||
|     d_RESULT_REG_IMAG_BASE_ADDR = 7; | ||||
|     d_RESULT_REG_DATA_REAL_BASE_ADDR = 6;  // no pilot tracking | ||||
|     d_RESULT_REG_DATA_IMAG_BASE_ADDR = 12; | ||||
|     d_SAMPLE_COUNTER_REG_ADDR_LSW = 13; | ||||
|     d_SAMPLE_COUNTER_REG_ADDR_MSW = 14; | ||||
|  | ||||
|     //        } | ||||
|  | ||||
|     //printf("d_SAMPLE_COUNTER_REG_ADDR = %d\n", d_SAMPLE_COUNTER_REG_ADDR); | ||||
|     //printf("mmmmmmmmmmmmm d_n_correlators = %d\n", d_n_correlators); | ||||
|     DLOG(INFO) << "TRACKING FPGA CLASS CREATED"; | ||||
| } | ||||
|  | ||||
|  | ||||
| fpga_multicorrelator_8sc::~fpga_multicorrelator_8sc() | ||||
| { | ||||
| 	delete[] d_ca_codes; | ||||
|     //delete[] d_ca_codes; | ||||
|     close_device(); | ||||
| } | ||||
|  | ||||
| @@ -214,73 +318,115 @@ bool fpga_multicorrelator_8sc::free() | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_multicorrelator_8sc::set_channel(unsigned int channel) | ||||
| void fpga_multicorrelator_8sc::set_channel(uint32_t channel) | ||||
| { | ||||
|     //printf("www trk set channel\n"); | ||||
|     char device_io_name[MAX_LENGTH_DEVICEIO_NAME];  // driver io name | ||||
|     d_channel = channel; | ||||
|  | ||||
|     // open the device corresponding to the assigned channel | ||||
|     std::string mergedname; | ||||
|     std::stringstream devicebasetemp; | ||||
|     int numdevice = d_device_base + d_channel; | ||||
|     int32_t numdevice = d_device_base + d_channel; | ||||
|     devicebasetemp << numdevice; | ||||
|     mergedname = d_device_name + devicebasetemp.str(); | ||||
|     strcpy(device_io_name, mergedname.c_str()); | ||||
|  | ||||
|     //printf("ppps opening device %s\n", device_io_name); | ||||
|  | ||||
|     if ((d_device_descriptor = open(device_io_name, O_RDWR | O_SYNC)) == -1) | ||||
|         { | ||||
|             LOG(WARNING) << "Cannot open deviceio" << device_io_name; | ||||
|             std::cout << "Cannot open deviceio" << device_io_name << std::endl; | ||||
|  | ||||
|             //printf("error opening device\n"); | ||||
|         } | ||||
|     d_map_base = reinterpret_cast<volatile unsigned *>(mmap(NULL, PAGE_SIZE, | ||||
|     //    else | ||||
|     //        { | ||||
|     //            std::cout << "deviceio" << device_io_name << " opened successfully" << std::endl; | ||||
|     // | ||||
|     //        } | ||||
|     d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(NULL, PAGE_SIZE, | ||||
|         PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0)); | ||||
|  | ||||
|     if (d_map_base == reinterpret_cast<void*>(-1)) | ||||
|     if (d_map_base == reinterpret_cast<void *>(-1)) | ||||
|         { | ||||
|             LOG(WARNING) << "Cannot map the FPGA tracking module " | ||||
|                          << d_channel << "into user memory"; | ||||
|             std::cout << "Cannot map deviceio" << device_io_name << std::endl; | ||||
|             //printf("error mapping registers\n"); | ||||
|         } | ||||
|     //    else | ||||
|     //        { | ||||
|     //            std::cout << "deviceio" << device_io_name << "mapped successfully" << std::endl; | ||||
|     //        } | ||||
|     //    else | ||||
|     //        { | ||||
|     //            printf("trk mapping registers succes\n"); // this is for debug -- remove ! | ||||
|     //        } | ||||
|  | ||||
|     // sanity check : check test register | ||||
|     unsigned writeval = TEST_REGISTER_TRACK_WRITEVAL; | ||||
|     unsigned readval; | ||||
|     uint32_t writeval = TEST_REGISTER_TRACK_WRITEVAL; | ||||
|     uint32_t readval; | ||||
|     readval = fpga_multicorrelator_8sc::fpga_acquisition_test_register(writeval); | ||||
|     if (writeval != readval) | ||||
|         { | ||||
|             LOG(WARNING) << "Test register sanity check failed"; | ||||
|             printf("tracking test register sanity check failed\n"); | ||||
|  | ||||
|             //printf("lslslls test sanity check reg failure\n"); | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             LOG(INFO) << "Test register sanity check success !"; | ||||
|             //printf("tracking test register sanity check success\n"); | ||||
|             //printf("lslslls test sanity check reg success\n"); | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| unsigned fpga_multicorrelator_8sc::fpga_acquisition_test_register( | ||||
|         unsigned writeval) | ||||
| uint32_t fpga_multicorrelator_8sc::fpga_acquisition_test_register( | ||||
|     uint32_t writeval) | ||||
| { | ||||
|     unsigned readval; | ||||
|     //printf("d_TEST_REG_ADDR = %d\n", d_TEST_REG_ADDR); | ||||
|  | ||||
|     uint32_t readval = 0; | ||||
|     // write value to test register | ||||
|     d_map_base[15] = writeval; | ||||
|     d_map_base[d_TEST_REG_ADDR] = writeval; | ||||
|     // read value from test register | ||||
|     readval = d_map_base[15]; | ||||
|     readval = d_map_base[d_TEST_REG_ADDR]; | ||||
|     // return read value | ||||
|     return readval; | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int PRN) | ||||
| void fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int32_t PRN) | ||||
| { | ||||
|     int k, s; | ||||
|     unsigned code_chip; | ||||
|     unsigned select_fpga_correlator; | ||||
|     select_fpga_correlator = 0; | ||||
|     uint32_t k; | ||||
|     uint32_t code_chip; | ||||
|     uint32_t select_pilot_corelator = LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT; | ||||
|     //    select_fpga_correlator = 0; | ||||
|  | ||||
|     for (s = 0; s < d_n_correlators; s++) | ||||
|         { | ||||
|             d_map_base[11] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER; | ||||
|             for (k = 0; k < d_code_length_chips; k++) | ||||
|     //printf("kkk d_n_correlators = %x\n", d_n_correlators); | ||||
|     //printf("kkk d_code_length_chips = %d\n", d_code_length_chips); | ||||
|     //printf("programming mems d map base %d\n", d_PROG_MEMS_ADDR); | ||||
|  | ||||
|     //FILE *fp; | ||||
|     //char str[80]; | ||||
|     //sprintf(str, "generated_code_PRN%d", PRN); | ||||
|     //fp = fopen(str,"w"); | ||||
|     //    for (s = 0; s < d_n_correlators; s++) | ||||
|     //        { | ||||
|  | ||||
|     //printf("kkk select_fpga_correlator = %x\n", select_fpga_correlator); | ||||
|  | ||||
|     d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER; | ||||
|     for (k = 0; k < d_code_length_chips * d_code_samples_per_chip; k++) | ||||
|         { | ||||
|             //if (d_local_code_in[k] == 1) | ||||
|                     if (d_ca_codes[((int(d_code_length)) * (PRN - 1)) + k] == 1) | ||||
|             //printf("kkk d_ca_codes %d = %d\n", k, d_ca_codes[((int(d_code_length)) * (PRN - 1)) + k]); | ||||
|             //fprintf(fp, "%d\n", d_ca_codes[((int(d_code_length_chips)) * d_code_samples_per_chip * (PRN - 1)) + k]); | ||||
|             if (d_ca_codes[((int(d_code_length_chips)) * d_code_samples_per_chip * (PRN - 1)) + k] == 1) | ||||
|                 { | ||||
|                     code_chip = 1; | ||||
|                 } | ||||
| @@ -288,51 +434,120 @@ void fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int PRN) | ||||
|                 { | ||||
|                     code_chip = 0; | ||||
|                 } | ||||
|  | ||||
|             // copy the local code to the FPGA memory one by one | ||||
|                     d_map_base[11] = LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY | ||||
|                             | code_chip | select_fpga_correlator; | ||||
|             d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY | code_chip;  // | select_fpga_correlator; | ||||
|         } | ||||
|             select_fpga_correlator = select_fpga_correlator | ||||
|                     + LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT; | ||||
|     //            select_fpga_correlator = select_fpga_correlator | ||||
|     //                    + LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT; | ||||
|     //        } | ||||
|     //fclose(fp); | ||||
|     //printf("kkk d_track_pilot = %d\n", d_track_pilot); | ||||
|     if (d_track_pilot) | ||||
|         { | ||||
|             //printf("kkk select_fpga_correlator = %x\n", select_fpga_correlator); | ||||
|  | ||||
|             d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER; | ||||
|             for (k = 0; k < d_code_length_chips * d_code_samples_per_chip; k++) | ||||
|                 { | ||||
|                     //if (d_local_code_in[k] == 1) | ||||
|                     if (d_data_codes[((int(d_code_length_chips)) * d_code_samples_per_chip * (PRN - 1)) + k] == 1) | ||||
|                         { | ||||
|                             code_chip = 1; | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             code_chip = 0; | ||||
|                         } | ||||
|                     //printf("%d %d | ", d_data_codes, code_chip); | ||||
|                     // copy the local code to the FPGA memory one by one | ||||
|                     d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY | code_chip | select_pilot_corelator; | ||||
|                 } | ||||
|         } | ||||
|     //printf("\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_multicorrelator_8sc::fpga_compute_code_shift_parameters(void) | ||||
| { | ||||
|     float temp_calculation; | ||||
|     int i; | ||||
|     int32_t i; | ||||
|  | ||||
|     //printf("ppp d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips); | ||||
|     for (i = 0; i < d_n_correlators; i++) | ||||
|         { | ||||
|             //printf("ppp d_shifts_chips %d = %f\n", i, d_shifts_chips[i]); | ||||
|             //printf("ppp d_code_samples_per_chip = %d\n", d_code_samples_per_chip); | ||||
|             temp_calculation = floor( | ||||
|                 d_shifts_chips[i] - d_rem_code_phase_chips); | ||||
|  | ||||
|             //printf("ppp d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips); | ||||
|             //printf("ppp temp calculation %d = %f ================================ \n", i, temp_calculation); | ||||
|             if (temp_calculation < 0) | ||||
|                 { | ||||
|                     temp_calculation = temp_calculation + d_code_length_chips; // % operator does not work as in Matlab with negative numbers | ||||
|                     temp_calculation = temp_calculation + (d_code_length_chips * d_code_samples_per_chip);  // % operator does not work as in Matlab with negative numbers | ||||
|                 } | ||||
|             d_initial_index[i] = static_cast<unsigned>( (static_cast<int>(temp_calculation)) % d_code_length_chips); | ||||
|             //printf("ppp d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips); | ||||
|             //printf("ppp temp calculation %d = %f ================================ \n", i, temp_calculation); | ||||
|             d_initial_index[i] = static_cast<uint32_t>((static_cast<int32_t>(temp_calculation)) % (d_code_length_chips * d_code_samples_per_chip)); | ||||
|             //printf("ppp d_initial_index %d = %d\n", i, d_initial_index[i]); | ||||
|             temp_calculation = fmod(d_shifts_chips[i] - d_rem_code_phase_chips, | ||||
|                 1.0); | ||||
|             //printf("ppp fmod %d = fmod(%f, 1) = %f\n", i, d_shifts_chips[i] - d_rem_code_phase_chips, temp_calculation); | ||||
|             if (temp_calculation < 0) | ||||
|                 { | ||||
|                     temp_calculation = temp_calculation + 1.0;  // fmod operator does not work as in Matlab with negative numbers | ||||
|                 } | ||||
|  | ||||
|             d_initial_interp_counter[i] = static_cast<uint32_t>(floor(MAX_CODE_RESAMPLER_COUNTER * temp_calculation)); | ||||
|             //printf("ppp d_initial_interp_counter %d = %d\n", i, d_initial_interp_counter[i]); | ||||
|             //printf("MAX_CODE_RESAMPLER_COUNTER = %d\n", MAX_CODE_RESAMPLER_COUNTER); | ||||
|         } | ||||
|     if (d_track_pilot) | ||||
|         { | ||||
|             //printf("tracking pilot !!!!!!!!!!!!!!!!\n"); | ||||
|             temp_calculation = floor( | ||||
|                 d_prompt_data_shift[0] - d_rem_code_phase_chips); | ||||
|  | ||||
|             if (temp_calculation < 0) | ||||
|                 { | ||||
|                     temp_calculation = temp_calculation + (d_code_length_chips * d_code_samples_per_chip);  // % operator does not work as in Matlab with negative numbers | ||||
|                 } | ||||
|             d_initial_index[d_n_correlators] = static_cast<uint32_t>((static_cast<int32_t>(temp_calculation)) % (d_code_length_chips * d_code_samples_per_chip)); | ||||
|             temp_calculation = fmod(d_prompt_data_shift[0] - d_rem_code_phase_chips, | ||||
|                 1.0); | ||||
|             if (temp_calculation < 0) | ||||
|                 { | ||||
|                     temp_calculation = temp_calculation + 1.0;  // fmod operator does not work as in Matlab with negative numbers | ||||
|                 } | ||||
|             d_initial_interp_counter[i] = static_cast<unsigned>( floor( MAX_CODE_RESAMPLER_COUNTER * temp_calculation)); | ||||
|             d_initial_interp_counter[d_n_correlators] = static_cast<uint32_t>(floor(MAX_CODE_RESAMPLER_COUNTER * temp_calculation)); | ||||
|         } | ||||
|     //while(1); | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_multicorrelator_8sc::fpga_configure_code_parameters_in_fpga(void) | ||||
| { | ||||
|     int i; | ||||
|     int32_t i; | ||||
|     for (i = 0; i < d_n_correlators; i++) | ||||
|         { | ||||
|             d_map_base[1 + i] = d_initial_index[i]; | ||||
|             d_map_base[1 + d_n_correlators + i] = d_initial_interp_counter[i]; | ||||
|             //printf("www writing d map base %d = d_initial_index %d  = %d\n", d_INITIAL_INDEX_REG_BASE_ADDR + i, i, d_initial_index[i]); | ||||
|             d_map_base[d_INITIAL_INDEX_REG_BASE_ADDR + i] = d_initial_index[i]; | ||||
|             //d_map_base[1 + d_n_correlators + i] = d_initial_interp_counter[i]; | ||||
|             //printf("www writing d map base %d = d_initial_interp_counter %d  = %d\n", d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + i, i, d_initial_interp_counter[i]); | ||||
|             d_map_base[d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + i] = d_initial_interp_counter[i]; | ||||
|         } | ||||
|     d_map_base[8] = d_code_length_chips - 1; // number of samples - 1 | ||||
|     if (d_track_pilot) | ||||
|         { | ||||
|             //printf("www writing d map base %d = d_initial_index %d  = %d\n", d_INITIAL_INDEX_REG_BASE_ADDR + d_n_correlators, d_n_correlators, d_initial_index[d_n_correlators]); | ||||
|             d_map_base[d_INITIAL_INDEX_REG_BASE_ADDR + d_n_correlators] = d_initial_index[d_n_correlators]; | ||||
|             //d_map_base[1 + d_n_correlators + i] = d_initial_interp_counter[i]; | ||||
|             //printf("www writing d map base %d = d_initial_interp_counter %d  = %d\n", d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + d_n_correlators, d_n_correlators, d_initial_interp_counter[d_n_correlators]); | ||||
|             d_map_base[d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + d_n_correlators] = d_initial_interp_counter[d_n_correlators]; | ||||
|         } | ||||
|  | ||||
|     //printf("www writing d map base %d = d_code_length_chips*d_code_samples_per_chip - 1  = %d\n", d_CODE_LENGTH_MINUS_1_REG_ADDR, (d_code_length_chips*d_code_samples_per_chip) - 1); | ||||
|     d_map_base[d_CODE_LENGTH_MINUS_1_REG_ADDR] = (d_code_length_chips * d_code_samples_per_chip) - 1;  // number of samples - 1 | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -340,78 +555,148 @@ void fpga_multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(void) | ||||
| { | ||||
|     float d_rem_carrier_phase_in_rad_temp; | ||||
|  | ||||
|     d_code_phase_step_chips_num = static_cast<unsigned>( roundf(MAX_CODE_RESAMPLER_COUNTER * d_code_phase_step_chips)); | ||||
|     d_code_phase_step_chips_num = static_cast<uint32_t>(roundf(MAX_CODE_RESAMPLER_COUNTER * d_code_phase_step_chips)); | ||||
|     if (d_code_phase_step_chips > 1.0) | ||||
|         { | ||||
|             printf("Warning : d_code_phase_step_chips = %f cannot be bigger than one\n", d_code_phase_step_chips); | ||||
|         } | ||||
|  | ||||
|     //printf("d_rem_carrier_phase_in_rad = %f\n", d_rem_carrier_phase_in_rad); | ||||
|  | ||||
|     if (d_rem_carrier_phase_in_rad > M_PI) | ||||
|         { | ||||
|             d_rem_carrier_phase_in_rad_temp = -2 * M_PI | ||||
|                     + d_rem_carrier_phase_in_rad; | ||||
|             d_rem_carrier_phase_in_rad_temp = -2 * M_PI + d_rem_carrier_phase_in_rad; | ||||
|         } | ||||
|     else if (d_rem_carrier_phase_in_rad < -M_PI) | ||||
|         { | ||||
|             d_rem_carrier_phase_in_rad_temp = 2 * M_PI | ||||
|                     + d_rem_carrier_phase_in_rad; | ||||
|             d_rem_carrier_phase_in_rad_temp = 2 * M_PI + d_rem_carrier_phase_in_rad; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             d_rem_carrier_phase_in_rad_temp = d_rem_carrier_phase_in_rad; | ||||
|         } | ||||
|     d_rem_carr_phase_rad_int = static_cast<int>( roundf( | ||||
|             (fabs(d_rem_carrier_phase_in_rad_temp) / M_PI) | ||||
|                     * pow(2, PHASE_CARR_NBITS_FRAC))); | ||||
|     d_rem_carr_phase_rad_int = static_cast<int32_t>(roundf( | ||||
|         (fabs(d_rem_carrier_phase_in_rad_temp) / M_PI) * pow(2, PHASE_CARR_NBITS_FRAC))); | ||||
|     if (d_rem_carrier_phase_in_rad_temp < 0) | ||||
|         { | ||||
|             d_rem_carr_phase_rad_int = -d_rem_carr_phase_rad_int; | ||||
|         } | ||||
|     d_phase_step_rad_int = static_cast<int>( roundf( | ||||
|     d_phase_step_rad_int = static_cast<int32_t>(roundf( | ||||
|         (fabs(d_phase_step_rad) / M_PI) * pow(2, PHASE_CARR_NBITS_FRAC)));  // the FPGA accepts a range for the phase step between -pi and +pi | ||||
|  | ||||
|     //printf("d_phase_step_rad_int = %d\n", d_phase_step_rad_int); | ||||
|     if (d_phase_step_rad < 0) | ||||
|         { | ||||
|             d_phase_step_rad_int = -d_phase_step_rad_int; | ||||
|         } | ||||
|  | ||||
|     //printf("d_phase_step_rad_int = %d\n", d_phase_step_rad_int); | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_multicorrelator_8sc::fpga_configure_signal_parameters_in_fpga(void) | ||||
| { | ||||
|     d_map_base[0] = d_code_phase_step_chips_num; | ||||
|     d_map_base[7] = d_correlator_length_samples - 1; | ||||
|     d_map_base[9] = d_rem_carr_phase_rad_int; | ||||
|     d_map_base[10] = d_phase_step_rad_int; | ||||
|     //printf("www d map base %d = d_code_phase_step_chips_num = %d\n", d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR, d_code_phase_step_chips_num); | ||||
|     d_map_base[d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR] = d_code_phase_step_chips_num; | ||||
|  | ||||
|     //printf("www d map base %d = d_correlator_length_samples - 1 = %d\n", d_NSAMPLES_MINUS_1_REG_ADDR, d_correlator_length_samples - 1); | ||||
|     d_map_base[d_NSAMPLES_MINUS_1_REG_ADDR] = d_correlator_length_samples - 1; | ||||
|  | ||||
|     //printf("www d map base %d = d_rem_carr_phase_rad_int = %d\n", d_REM_CARR_PHASE_RAD_REG_ADDR, d_rem_carr_phase_rad_int); | ||||
|     d_map_base[d_REM_CARR_PHASE_RAD_REG_ADDR] = d_rem_carr_phase_rad_int; | ||||
|  | ||||
|     //printf("www d map base %d = d_phase_step_rad_int = %d\n", d_PHASE_STEP_RAD_REG_ADDR, d_phase_step_rad_int); | ||||
|     d_map_base[d_PHASE_STEP_RAD_REG_ADDR] = d_phase_step_rad_int; | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_multicorrelator_8sc::fpga_launch_multicorrelator_fpga(void) | ||||
| { | ||||
|     // enable interrupts | ||||
|     int reenable = 1; | ||||
|     write(d_device_descriptor, reinterpret_cast<void*>(&reenable), sizeof(int)); | ||||
|     int32_t reenable = 1; | ||||
|     write(d_device_descriptor, reinterpret_cast<void *>(&reenable), sizeof(int32_t)); | ||||
|  | ||||
|     // writing 1 to reg 14 launches the tracking | ||||
|     d_map_base[14] = 1;  | ||||
|     //printf("www writing 1 to d map base %d = start flag\n", d_START_FLAG_ADDR); | ||||
|     d_map_base[d_START_FLAG_ADDR] = 1; | ||||
|     //while(1); | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_multicorrelator_8sc::read_tracking_gps_results(void) | ||||
| { | ||||
|     int readval_real; | ||||
|     int readval_imag; | ||||
|     int k; | ||||
|     int32_t readval_real; | ||||
|     int32_t readval_imag; | ||||
|     int32_t k; | ||||
|  | ||||
|     //printf("www reading trk results\n"); | ||||
|     for (k = 0; k < d_n_correlators; k++) | ||||
|         { | ||||
|             readval_real = d_map_base[1 + k]; | ||||
|             if (readval_real >= 1048576) // 0x100000 (21 bits two's complement) | ||||
|                 { | ||||
|                     readval_real = -2097152 + readval_real; | ||||
|                 } | ||||
|             readval_real = d_map_base[d_RESULT_REG_REAL_BASE_ADDR + k]; | ||||
|             //printf("read real before checking d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_real); | ||||
|             ////            if (readval_real > debug_max_readval_real[k]) | ||||
|             ////                { | ||||
|             ////                    debug_max_readval_real[k] = readval_real; | ||||
|             ////                } | ||||
|             //            if (readval_real >= d_result_SAT_value) // 0x100000 (21 bits two's complement) | ||||
|             //                { | ||||
|             //                    readval_real = -2*d_result_SAT_value + readval_real; | ||||
|             //                } | ||||
|             ////            if (readval_real > debug_max_readval_real_after_check[k]) | ||||
|             ////                { | ||||
|             ////                    debug_max_readval_real_after_check[k] = readval_real; | ||||
|             ////                } | ||||
|             //printf("read real d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_real); | ||||
|             readval_imag = d_map_base[d_RESULT_REG_IMAG_BASE_ADDR + k]; | ||||
|             //printf("read imag before checking d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_imag); | ||||
|             ////            if (readval_imag > debug_max_readval_imag[k]) | ||||
|             ////                { | ||||
|             ////                    debug_max_readval_imag[k] = readval_imag; | ||||
|             ////                } | ||||
|             // | ||||
|             //            if (readval_imag >= d_result_SAT_value) // 0x100000 (21 bits two's complement) | ||||
|             //                { | ||||
|             //                    readval_imag = -2*d_result_SAT_value + readval_imag; | ||||
|             //                } | ||||
|             ////            if (readval_imag > debug_max_readval_imag_after_check[k]) | ||||
|             ////                { | ||||
|             ////                    debug_max_readval_imag_after_check[k] = readval_real; | ||||
|             ////                } | ||||
|             //printf("read imag d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_imag); | ||||
|             d_corr_out[k] = gr_complex(readval_real, readval_imag); | ||||
|  | ||||
|             readval_imag = d_map_base[1 + d_n_correlators + k]; | ||||
|             if (readval_imag >= 1048576) // 0x100000 (21 bits two's complement) | ||||
|                 { | ||||
|                     readval_imag = -2097152 + readval_imag; | ||||
|             //      if (printcounter > 100) | ||||
|             //          { | ||||
|             //              printcounter = 0; | ||||
|             //              for (int32_t ll=0;ll<d_n_correlators;ll++) | ||||
|             //                  { | ||||
|             //                      printf("debug_max_readval_real %d = %d\n", ll, debug_max_readval_real[ll]); | ||||
|             //                      printf("debug_max_readval_imag %d = %d\n", ll, debug_max_readval_imag[ll]); | ||||
|             //                      printf("debug_max_readval_real_%d after_check = %d\n", ll, debug_max_readval_real_after_check[ll]); | ||||
|             //                      printf("debug_max_readval_imag_%d after_check = %d\n", ll, debug_max_readval_imag_after_check[ll]); | ||||
|             //                  } | ||||
|             // | ||||
|             //                } | ||||
|             //            else | ||||
|             //                { | ||||
|             //                    printcounter = printcounter + 1; | ||||
|             //                } | ||||
|         } | ||||
|             d_corr_out[k] = gr_complex(readval_real,readval_imag); | ||||
|     if (d_track_pilot) | ||||
|         { | ||||
|             //printf("reading pilot !!!\n"); | ||||
|             readval_real = d_map_base[d_RESULT_REG_DATA_REAL_BASE_ADDR]; | ||||
|             //            if (readval_real >= d_result_SAT_value) // 0x100000 (21 bits two's complement) | ||||
|             //                { | ||||
|             //                    readval_real = -2*d_result_SAT_value + readval_real; | ||||
|             //                } | ||||
|  | ||||
|             readval_imag = d_map_base[d_RESULT_REG_DATA_IMAG_BASE_ADDR]; | ||||
|             //            if (readval_imag >= d_result_SAT_value) // 0x100000 (21 bits two's complement) | ||||
|             //                { | ||||
|             //                    readval_imag = -2*d_result_SAT_value + readval_imag; | ||||
|             //                } | ||||
|             d_Prompt_Data[0] = gr_complex(readval_real, readval_imag); | ||||
|         } | ||||
| } | ||||
|  | ||||
| @@ -419,20 +704,17 @@ void fpga_multicorrelator_8sc::read_tracking_gps_results(void) | ||||
| void fpga_multicorrelator_8sc::unlock_channel(void) | ||||
| { | ||||
|     // unlock the channel to let the next samples go through | ||||
|     d_map_base[12] = 1; // unlock the channel | ||||
|     //printf("www writing 1 to d map base %d = drop samples\n", d_DROP_SAMPLES_REG_ADDR); | ||||
|     d_map_base[d_DROP_SAMPLES_REG_ADDR] = 1;  // unlock the channel | ||||
| } | ||||
|  | ||||
| void fpga_multicorrelator_8sc::close_device() | ||||
| { | ||||
|     unsigned * aux = const_cast<unsigned*>(d_map_base); | ||||
|     if (munmap(static_cast<void*>(aux), PAGE_SIZE) == -1) | ||||
|     uint32_t *aux = const_cast<uint32_t *>(d_map_base); | ||||
|     if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1) | ||||
|         { | ||||
|             printf("Failed to unmap memory uio\n"); | ||||
|         } | ||||
| /*    else | ||||
|         { | ||||
|             printf("memory uio unmapped\n"); | ||||
|         } */ | ||||
|     close(d_device_descriptor); | ||||
| } | ||||
|  | ||||
| @@ -440,19 +722,20 @@ void fpga_multicorrelator_8sc::close_device() | ||||
| void fpga_multicorrelator_8sc::lock_channel(void) | ||||
| { | ||||
|     // lock the channel for processing | ||||
|     d_map_base[12] = 0; // lock the channel | ||||
|     //printf("www writing 0 to d map base %d = drop samples\n", d_DROP_SAMPLES_REG_ADDR); | ||||
|     d_map_base[d_DROP_SAMPLES_REG_ADDR] = 0;  // lock the channel | ||||
| } | ||||
|  | ||||
| void fpga_multicorrelator_8sc::read_sample_counters(int *sample_counter, int *secondary_sample_counter, int *counter_corr_0_in, int *counter_corr_0_out) | ||||
| { | ||||
| 	*sample_counter = d_map_base[11]; | ||||
| 	*secondary_sample_counter = d_map_base[8]; | ||||
| 	*counter_corr_0_in = d_map_base[10]; | ||||
| 	*counter_corr_0_out = d_map_base[9]; | ||||
| //void fpga_multicorrelator_8sc::read_sample_counters(int32_t *sample_counter, int32_t *secondary_sample_counter, int32_t *counter_corr_0_in, int32_t *counter_corr_0_out) | ||||
| //{ | ||||
| //	*sample_counter = d_map_base[11]; | ||||
| //	*secondary_sample_counter = d_map_base[8]; | ||||
| //	*counter_corr_0_in = d_map_base[10]; | ||||
| //	*counter_corr_0_out = d_map_base[9]; | ||||
| // | ||||
| //} | ||||
|  | ||||
| } | ||||
|  | ||||
| void fpga_multicorrelator_8sc::reset_multicorrelator(void) | ||||
| { | ||||
| 	d_map_base[14] = 2; // writing a 2 to d_map_base[14] resets the multicorrelator    | ||||
| } | ||||
| //void fpga_multicorrelator_8sc::reset_multicorrelator(void) | ||||
| //{ | ||||
| //	d_map_base[14] = 2; // writing a 2 to d_map_base[14] resets the multicorrelator | ||||
| //} | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /*! | ||||
|  * \file fpga_multicorrelator_8sc.h | ||||
|  * \brief High optimized FPGA vector correlator class for lv_16sc_t (short int complex) | ||||
|  * \brief High optimized FPGA vector correlator class for lv_16sc_t (short int32_t complex) | ||||
|  * \authors <ul> | ||||
|  * 			<li> Marc Majoral, 2017. mmajoral(at)cttc.cat | ||||
|  *          <li> Javier Arribas, 2016. jarribas(at)cttc.es | ||||
| @@ -11,7 +11,7 @@ | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2017  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -29,7 +29,7 @@ | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
| @@ -39,6 +39,7 @@ | ||||
|  | ||||
| #include <gnuradio/block.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr.h> | ||||
| #include <cstdint> | ||||
|  | ||||
| #define MAX_LENGTH_DEVICEIO_NAME 50 | ||||
|  | ||||
| @@ -48,84 +49,121 @@ | ||||
| class fpga_multicorrelator_8sc | ||||
| { | ||||
| public: | ||||
|     fpga_multicorrelator_8sc(int n_correlators, std::string device_name, | ||||
|         unsigned int device_base, int *ca_codes, unsigned int code_length); | ||||
|     fpga_multicorrelator_8sc(int32_t n_correlators, std::string device_name, | ||||
|         uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, uint32_t multicorr_type, uint32_t code_samples_per_chip); | ||||
|     ~fpga_multicorrelator_8sc(); | ||||
|     //bool set_output_vectors(gr_complex* corr_out); | ||||
|     void set_output_vectors(gr_complex *corr_out); | ||||
|     void set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data); | ||||
|     //    bool set_local_code_and_taps( | ||||
|     //            int code_length_chips, const int* local_code_in, | ||||
|     //            float *shifts_chips, int PRN); | ||||
|     //            int32_t code_length_chips, const int* local_code_in, | ||||
|     //            float *shifts_chips, int32_t PRN); | ||||
|     //bool set_local_code_and_taps( | ||||
|     void set_local_code_and_taps( | ||||
|         int code_length_chips, | ||||
|         float *shifts_chips, int PRN); | ||||
|         //            int32_t code_length_chips, | ||||
|         float *shifts_chips, float *prompt_data_shift, int32_t PRN); | ||||
|     //bool set_output_vectors(lv_16sc_t* corr_out); | ||||
|     void update_local_code(float rem_code_phase_chips); | ||||
|     //bool Carrier_wipeoff_multicorrelator_resampler( | ||||
|     void Carrier_wipeoff_multicorrelator_resampler( | ||||
|         float rem_carrier_phase_in_rad, float phase_step_rad, | ||||
|         float rem_code_phase_chips, float code_phase_step_chips, | ||||
|         int signal_length_samples); | ||||
|         int32_t signal_length_samples); | ||||
|     bool free(); | ||||
|     void set_channel(unsigned int channel); | ||||
|     void set_initial_sample(int samples_offset); | ||||
|     int read_sample_counter(); | ||||
|     void set_channel(uint32_t channel); | ||||
|     void set_initial_sample(uint64_t samples_offset); | ||||
|     uint64_t read_sample_counter(); | ||||
|     void lock_channel(void); | ||||
|     void unlock_channel(void); | ||||
|     void read_sample_counters(int *sample_counter, int *secondary_sample_counter, int *counter_corr_0_in, int *counter_corr_0_out);  // debug | ||||
|  | ||||
|     //void read_sample_counters(int32_t *sample_counter, int32_t *secondary_sample_counter, int32_t *counter_corr_0_in, int32_t *counter_corr_0_out); // debug | ||||
|  | ||||
| private: | ||||
|     //const int *d_local_code_in; | ||||
|     //const int32_t *d_local_code_in; | ||||
|     gr_complex *d_corr_out; | ||||
|     gr_complex *d_Prompt_Data; | ||||
|     float *d_shifts_chips; | ||||
|     int d_code_length_chips; | ||||
|     int d_n_correlators; | ||||
|     float *d_prompt_data_shift; | ||||
|     int32_t d_code_length_chips; | ||||
|     int32_t d_n_correlators; | ||||
|  | ||||
|     // data related to the hardware module and the driver | ||||
|     int d_device_descriptor;        // driver descriptor | ||||
|     volatile unsigned *d_map_base;  // driver memory map | ||||
|     int32_t d_device_descriptor;    // driver descriptor | ||||
|     volatile uint32_t *d_map_base;  // driver memory map | ||||
|  | ||||
|     // configuration data received from the interface | ||||
|     unsigned int d_channel;  // channel number | ||||
|     unsigned d_correlator_length_samples; | ||||
|     uint32_t d_channel;       // channel number | ||||
|     uint32_t d_ncorrelators;  // number of correlators | ||||
|     uint32_t d_correlator_length_samples; | ||||
|     float d_rem_code_phase_chips; | ||||
|     float d_code_phase_step_chips; | ||||
|     float d_rem_carrier_phase_in_rad; | ||||
|     float d_phase_step_rad; | ||||
|  | ||||
|     // configuration data computed in the format that the FPGA expects | ||||
|     unsigned *d_initial_index; | ||||
|     unsigned *d_initial_interp_counter; | ||||
|     unsigned d_code_phase_step_chips_num; | ||||
|     int d_rem_carr_phase_rad_int; | ||||
|     int d_phase_step_rad_int; | ||||
|     unsigned d_initial_sample_counter; | ||||
|     uint32_t *d_initial_index; | ||||
|     uint32_t *d_initial_interp_counter; | ||||
|     uint32_t d_code_phase_step_chips_num; | ||||
|     int32_t d_rem_carr_phase_rad_int; | ||||
|     int32_t d_phase_step_rad_int; | ||||
|     uint64_t d_initial_sample_counter; | ||||
|  | ||||
|     // driver | ||||
|     std::string d_device_name; | ||||
|     unsigned int d_device_base; | ||||
|     uint32_t d_device_base; | ||||
|  | ||||
|     int32_t *d_ca_codes; | ||||
|     int32_t *d_data_codes; | ||||
|  | ||||
|     int *d_ca_codes; | ||||
|     //uint32_t d_code_length; // nominal number of chips | ||||
|  | ||||
|     unsigned int d_code_length;  // nominal number of chips | ||||
|     uint32_t d_code_samples_per_chip; | ||||
|     bool d_track_pilot; | ||||
|  | ||||
|     uint32_t d_multicorr_type; | ||||
|  | ||||
|     // register addresses | ||||
|     // write-only regs | ||||
|     uint32_t d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR; | ||||
|     uint32_t d_INITIAL_INDEX_REG_BASE_ADDR; | ||||
|     uint32_t d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR; | ||||
|     uint32_t d_NSAMPLES_MINUS_1_REG_ADDR; | ||||
|     uint32_t d_CODE_LENGTH_MINUS_1_REG_ADDR; | ||||
|     uint32_t d_REM_CARR_PHASE_RAD_REG_ADDR; | ||||
|     uint32_t d_PHASE_STEP_RAD_REG_ADDR; | ||||
|     uint32_t d_PROG_MEMS_ADDR; | ||||
|     uint32_t d_DROP_SAMPLES_REG_ADDR; | ||||
|     uint32_t d_INITIAL_COUNTER_VALUE_REG_ADDR_LSW; | ||||
|     uint32_t d_INITIAL_COUNTER_VALUE_REG_ADDR_MSW; | ||||
|     uint32_t d_START_FLAG_ADDR; | ||||
|     // read-write regs | ||||
|     uint32_t d_TEST_REG_ADDR; | ||||
|     // read-only regs | ||||
|     uint32_t d_RESULT_REG_REAL_BASE_ADDR; | ||||
|     uint32_t d_RESULT_REG_IMAG_BASE_ADDR; | ||||
|     uint32_t d_RESULT_REG_DATA_REAL_BASE_ADDR; | ||||
|     uint32_t d_RESULT_REG_DATA_IMAG_BASE_ADDR; | ||||
|     uint32_t d_SAMPLE_COUNTER_REG_ADDR_LSW; | ||||
|     uint32_t d_SAMPLE_COUNTER_REG_ADDR_MSW; | ||||
|  | ||||
|     // private functions | ||||
|     unsigned fpga_acquisition_test_register(unsigned writeval); | ||||
|     void fpga_configure_tracking_gps_local_code(int PRN); | ||||
|     uint32_t fpga_acquisition_test_register(uint32_t writeval); | ||||
|     void fpga_configure_tracking_gps_local_code(int32_t PRN); | ||||
|     void fpga_compute_code_shift_parameters(void); | ||||
|     void fpga_configure_code_parameters_in_fpga(void); | ||||
|     void fpga_compute_signal_parameters_in_fpga(void); | ||||
|     void fpga_configure_signal_parameters_in_fpga(void); | ||||
|     void fpga_launch_multicorrelator_fpga(void); | ||||
|     void read_tracking_gps_results(void); | ||||
|     void reset_multicorrelator(void); | ||||
|     //void reset_multicorrelator(void); | ||||
|     void close_device(void); | ||||
|  | ||||
|     // debug | ||||
|     //unsigned int first_time = 1; | ||||
|     uint32_t d_result_SAT_value; | ||||
|  | ||||
|     int32_t debug_max_readval_real[5] = {0, 0, 0, 0, 0}; | ||||
|     int32_t debug_max_readval_imag[5] = {0, 0, 0, 0, 0}; | ||||
|  | ||||
|     int32_t debug_max_readval_real_after_check[5] = {0, 0, 0, 0, 0}; | ||||
|     int32_t debug_max_readval_imag_after_check[5] = {0, 0, 0, 0, 0}; | ||||
|     int32_t printcounter = 0; | ||||
| }; | ||||
|  | ||||
| #endif /* GNSS_SDR_FPGA_MULTICORRELATOR_H_ */ | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|  * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com | ||||
|  *         Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  *         Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  *         Marc Majoral, 2018. mmajoral(at)cttc.es | ||||
|  * | ||||
|  * This class encapsulates the complexity behind the instantiation | ||||
|  * of GNSS blocks. | ||||
| @@ -110,7 +111,15 @@ | ||||
|  | ||||
| #if ENABLE_FPGA | ||||
| #include "gps_l1_ca_pcps_acquisition_fpga.h" | ||||
| #include "gps_l2_m_pcps_acquisition_fpga.h" | ||||
| #include "galileo_e1_pcps_ambiguous_acquisition_fpga.h" | ||||
| #include "galileo_e5a_pcps_acquisition_fpga.h" | ||||
| #include "gps_l5i_pcps_acquisition_fpga.h" | ||||
| #include "gps_l1_ca_dll_pll_tracking_fpga.h" | ||||
| #include "gps_l2_m_dll_pll_tracking_fpga.h" | ||||
| #include "galileo_e1_dll_pll_veml_tracking_fpga.h" | ||||
| #include "galileo_e5a_dll_pll_tracking_fpga.h" | ||||
| #include "gps_l5_dll_pll_tracking_fpga.h" | ||||
| #endif | ||||
|  | ||||
| #if OPENCL_BLOCKS | ||||
| @@ -163,7 +172,11 @@ using google::LogMessage; | ||||
|  | ||||
|  | ||||
| GNSSBlockFactory::GNSSBlockFactory() {} | ||||
|  | ||||
|  | ||||
| GNSSBlockFactory::~GNSSBlockFactory() {} | ||||
|  | ||||
|  | ||||
| std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetSignalSource( | ||||
|     std::shared_ptr<ConfigurationInterface> configuration, gr::msg_queue::sptr queue, int ID) | ||||
| { | ||||
| @@ -1389,18 +1402,42 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock( | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("GPS_L2_M_PCPS_Acquisition_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GpsL2MPcpsAcquisitionFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0) | ||||
|         { | ||||
|             std::unique_ptr<AcquisitionInterface> block_(new GpsL5iPcpsAcquisition(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("GPS_L5i_PCPS_Acquisition_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<AcquisitionInterface> block_(new GpsL5iPcpsAcquisitionFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GalileoE1PcpsAmbiguousAcquisition(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GalileoE1PcpsAmbiguousAcquisitionFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("Galileo_E1_PCPS_8ms_Ambiguous_Acquisition") == 0) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GalileoE1Pcps8msAmbiguousAcquisition(configuration.get(), role, in_streams, | ||||
| @@ -1431,6 +1468,14 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock( | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("Galileo_E5a_Pcps_Acquisition_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GalileoE5aPcpsAcquisitionFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition") == 0) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GalileoE1PcpsQuickSyncAmbiguousAcquisition(configuration.get(), role, in_streams, | ||||
| @@ -1482,12 +1527,28 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock( | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GpsL2MDllPllTrackingFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if ((implementation.compare("GPS_L5i_DLL_PLL_Tracking") == 0) or (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0)) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GpsL5DllPllTracking(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if ((implementation.compare("GPS_L5i_DLL_PLL_Tracking_Fpga") == 0) or (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GpsL5DllPllTrackingFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
| #if CUDA_GPU_ACCEL | ||||
|     else if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_GPU") == 0) | ||||
|         { | ||||
| @@ -1502,6 +1563,14 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock( | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<TrackingInterface> block_(new GalileoE1DllPllVemlTrackingFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("Galileo_E1_TCP_CONNECTOR_Tracking") == 0) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GalileoE1TcpConnectorTracking(configuration.get(), role, in_streams, | ||||
| @@ -1514,6 +1583,14 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock( | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GalileoE5aDllPllTrackingFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("GLONASS_L1_CA_DLL_PLL_Tracking") == 0) | ||||
|         { | ||||
|             std::unique_ptr<GNSSBlockInterface> block_(new GlonassL1CaDllPllTracking(configuration.get(), role, in_streams, | ||||
| @@ -1682,18 +1759,42 @@ std::unique_ptr<AcquisitionInterface> GNSSBlockFactory::GetAcqBlock( | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("GPS_L2_M_PCPS_Acquisition_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<AcquisitionInterface> block_(new GpsL2MPcpsAcquisitionFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0) | ||||
|         { | ||||
|             std::unique_ptr<AcquisitionInterface> block_(new GpsL5iPcpsAcquisition(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("GPS_L5i_PCPS_Acquisition_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<AcquisitionInterface> block_(new GpsL5iPcpsAcquisitionFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0) | ||||
|         { | ||||
|             std::unique_ptr<AcquisitionInterface> block_(new GalileoE1PcpsAmbiguousAcquisition(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<AcquisitionInterface> block_(new GalileoE1PcpsAmbiguousAcquisitionFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("Galileo_E1_PCPS_8ms_Ambiguous_Acquisition") == 0) | ||||
|         { | ||||
|             std::unique_ptr<AcquisitionInterface> block_(new GalileoE1Pcps8msAmbiguousAcquisition(configuration.get(), role, in_streams, | ||||
| @@ -1731,6 +1832,14 @@ std::unique_ptr<AcquisitionInterface> GNSSBlockFactory::GetAcqBlock( | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("Galileo_E5a_Pcps_Acquisition_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<AcquisitionInterface> block_(new GalileoE5aPcpsAcquisitionFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0) | ||||
|         { | ||||
|             std::unique_ptr<AcquisitionInterface> block_(new GlonassL1CaPcpsAcquisition(configuration.get(), role, in_streams, | ||||
| @@ -1793,6 +1902,14 @@ std::unique_ptr<TrackingInterface> GNSSBlockFactory::GetTrkBlock( | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<TrackingInterface> block_(new GalileoE1DllPllVemlTrackingFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("Galileo_E1_TCP_CONNECTOR_Tracking") == 0) | ||||
|         { | ||||
|             std::unique_ptr<TrackingInterface> block_(new GalileoE1TcpConnectorTracking(configuration.get(), role, in_streams, | ||||
| @@ -1805,18 +1922,42 @@ std::unique_ptr<TrackingInterface> GNSSBlockFactory::GetTrkBlock( | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<TrackingInterface> block_(new GalileoE5aDllPllTrackingFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0) | ||||
|         { | ||||
|             std::unique_ptr<TrackingInterface> block_(new GpsL2MDllPllTracking(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking_Fpga") == 0) | ||||
|         { | ||||
|             std::unique_ptr<TrackingInterface> block_(new GpsL2MDllPllTrackingFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
|     else if ((implementation.compare("GPS_L5i_DLL_PLL_Tracking") == 0) or (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0)) | ||||
|         { | ||||
|             std::unique_ptr<TrackingInterface> block_(new GpsL5DllPllTracking(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #if ENABLE_FPGA | ||||
|     else if ((implementation.compare("GPS_L5i_DLL_PLL_Tracking_Fpga") == 0) or (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) | ||||
|         { | ||||
|             std::unique_ptr<TrackingInterface> block_(new GpsL5DllPllTrackingFpga(configuration.get(), role, in_streams, | ||||
|                 out_streams)); | ||||
|             block = std::move(block_); | ||||
|         } | ||||
| #endif | ||||
| #if CUDA_GPU_ACCEL | ||||
|     else if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_GPU") == 0) | ||||
|         { | ||||
|   | ||||
| @@ -211,6 +211,7 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) | ||||
|    find_package(GPSTK) | ||||
|    if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) | ||||
|       message(STATUS "GPSTk v${GNSSSDR_GPSTK_LOCAL_VERSION} will be automatically downloaded and built when doing 'make'.") | ||||
|  | ||||
|  #     if(NOT ENABLE_FPGA) | ||||
|           if(CMAKE_VERSION VERSION_LESS 3.2) | ||||
|            ExternalProject_Add( | ||||
|   | ||||
| @@ -149,6 +149,9 @@ DECLARE_string(log_dir); | ||||
| #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" | ||||
| #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc" | ||||
| #include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc" | ||||
| #if ENABLE_FPGA | ||||
| #include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc" | ||||
| #endif | ||||
| #include "unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc" | ||||
| #include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc" | ||||
| #endif | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user
	 Carles Fernandez
					Carles Fernandez