mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-30 23:03:05 +00:00 
			
		
		
		
	cleaned the FPGA acquisition code
This commit is contained in:
		| @@ -1,12 +1,13 @@ | ||||
| /*! | ||||
|  * \file galileo_e1_pcps_ambiguous_acquisition.cc | ||||
|  * \file galileo_e1_pcps_ambiguous_acquisition_fpga.cc | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  Galileo E1 Signals | ||||
|  *  Galileo E1 Signals for the FPGA | ||||
|  * \author Marc Majoral, 2019. mmajoral(at)cttc.es | ||||
|  * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -27,7 +28,7 @@ | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  */  | ||||
|  | ||||
| #include "galileo_e1_pcps_ambiguous_acquisition_fpga.h" | ||||
| #include "Galileo_E1.h" | ||||
| @@ -50,7 +51,6 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( | ||||
|                                 in_streams_(in_streams), | ||||
|                                 out_streams_(out_streams) | ||||
| { | ||||
|     //printf("top acq constructor start\n"); | ||||
|     pcpsconf_fpga_t acq_parameters; | ||||
|     configuration_ = configuration; | ||||
|  | ||||
| @@ -68,67 +68,27 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( | ||||
|     float downsampling_factor = configuration_->property(role + ".downsampling_factor", 4.0); | ||||
|     acq_parameters.downsampling_factor = downsampling_factor; | ||||
|  | ||||
|     //fs_in = fs_in/2.0; // downampling filter | ||||
|     //printf("fs_in pre downsampling = %ld\n", fs_in); | ||||
|     printf("fs_in pre downsampling = %ld\n", fs_in); | ||||
|  | ||||
|     fs_in = fs_in/downsampling_factor; | ||||
|  | ||||
|     printf("fs_in post downsampling = %ld\n", fs_in); | ||||
|  | ||||
|     //printf("fs_in post downsampling = %ld\n", fs_in); | ||||
|  | ||||
|     acq_parameters.fs_in = fs_in; | ||||
|     //if_ = configuration_->property(role + ".if", 0); | ||||
|     //acq_parameters.freq = if_; | ||||
|  | ||||
|     //  dump_ = configuration_->property(role + ".dump", false); | ||||
|     //  acq_parameters.dump = dump_; | ||||
|     //  blocking_ = configuration_->property(role + ".blocking", true); | ||||
|     //    acq_parameters.blocking = blocking_; | ||||
|     doppler_max_ = configuration_->property(role + ".doppler_max", 5000); | ||||
|     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)  ----------------- | ||||
|     auto code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (GALILEO_E1_CODE_CHIP_RATE_HZ / GALILEO_E1_B_CODE_LENGTH_CHIPS))); | ||||
|     //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*2)); | ||||
|     unsigned int nsamples_total = pow(2, nbits); | ||||
|     unsigned int vector_length = nsamples_total; | ||||
|     printf("acq adapter vector_length = %d\n", vector_length); | ||||
|     //printf("acq adapter nsamples_total (= vector_length) = %d\n", vector_length); | ||||
|     unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0); | ||||
|     printf("select queue = %d\n", select_queue_Fpga); | ||||
|  | ||||
|     acq_parameters.select_queue_Fpga = select_queue_Fpga; | ||||
|     std::string default_device_name = "/dev/uio0"; | ||||
| @@ -138,7 +98,7 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( | ||||
|     acq_parameters.samples_per_code = nsamples_total; | ||||
|     acq_parameters.excludelimit = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / GALILEO_E1_CODE_CHIP_RATE_HZ)); | ||||
|  | ||||
|     // compute all the GALILEO E1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time | ||||
|     // compute all the GALILEO E1 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time | ||||
|     // a channel is assigned) | ||||
|     auto* fft_if = new gr::fft::fft_complex(nsamples_total, true);  // Direct FFT | ||||
|     auto* code = new std::complex<float>[nsamples_total];           // buffer for the local code | ||||
| @@ -146,20 +106,13 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( | ||||
|     d_all_fft_codes_ = new lv_16sc_t[nsamples_total * GALILEO_E1_NUMBER_OF_CODES];  // memory containing all the possible fft codes for PRN 0 to 32 | ||||
|     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, | ||||
| @@ -172,56 +125,22 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( | ||||
|                     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); | ||||
|  | ||||
|         for (int s = code_length; s < 2*code_length; s++) | ||||
|             { | ||||
|                 code[s] = code[s - code_length]; | ||||
|                 //code[s] = 0; | ||||
|             } | ||||
|  | ||||
|  | ||||
| //        // fill in zero padding | ||||
|         // fill in zero padding | ||||
|         for (int s = 2*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 | ||||
| @@ -237,109 +156,34 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( | ||||
|             } | ||||
|         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, 9) - 1) / max)), | ||||
|                     static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 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_; | ||||
|  | ||||
|     // reference for the FPGA FFT-IFFT attenuation factor | ||||
|     acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 14); | ||||
|  | ||||
|     acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
|     channel_ = 0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = nullptr; | ||||
|  | ||||
|     // temporary buffers that we can delete | ||||
|     delete[] code; | ||||
|     delete fft_if; | ||||
|     delete[] fft_codes_padded; | ||||
|  | ||||
|     acq_parameters.total_block_exp = 12; | ||||
|  | ||||
|     acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
|     //    stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); | ||||
|     //    DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; | ||||
|  | ||||
|     //    if (item_type_.compare("cbyte") == 0) | ||||
|     //        { | ||||
|     //            cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); | ||||
|     //            float_to_complex_ = gr::blocks::float_to_complex::make(); | ||||
|     //        } | ||||
|  | ||||
|     channel_ = 0; | ||||
|     //threshold_ = 0.0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = nullptr; | ||||
|     //printf("top acq constructor end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| GalileoE1PcpsAmbiguousAcquisitionFpga::~GalileoE1PcpsAmbiguousAcquisitionFpga() | ||||
| { | ||||
|     //printf("top acq destructor start\n"); | ||||
|     //delete[] code_; | ||||
|     delete[] d_all_fft_codes_; | ||||
|     //printf("top acq destructor end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -352,266 +196,88 @@ void GalileoE1PcpsAmbiguousAcquisitionFpga::stop_acquisition() | ||||
|  | ||||
| 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"); | ||||
|     // This command starts the acquisition process | ||||
|     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; | ||||
| //} | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::set_single_doppler_flag(unsigned int single_doppler_flag) | ||||
| { | ||||
| 	acquisition_fpga_->set_single_doppler_flag(single_doppler_flag); | ||||
| } | ||||
| // this function is only used for the unit tests | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::read_acquisition_results(uint32_t *max_index, | ||||
|     float *max_magnitude, float *second_magnitude, uint64_t *initial_sample, uint32_t *doppler_index, uint32_t *total_fft_scaling_factor) | ||||
|  | ||||
| { | ||||
| 	acquisition_fpga_->read_acquisition_results(max_index, max_magnitude, second_magnitude, | ||||
| 	        initial_sample, doppler_index, total_fft_scaling_factor); | ||||
| } | ||||
|  | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void GalileoE1PcpsAmbiguousAcquisitionFpga::reset_acquisition(void) | ||||
| { | ||||
| 	acquisition_fpga_->reset_acquisition(); | ||||
| } | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| //void GalileoE1PcpsAmbiguousAcquisitionFpga::read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor) | ||||
| //{ | ||||
| //	acquisition_fpga_->read_fpga_total_scale_factor(total_scale_factor, fw_scale_factor); | ||||
| //} | ||||
|  | ||||
| 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"); | ||||
| } | ||||
|   | ||||
| @@ -1,12 +1,13 @@ | ||||
| /*! | ||||
|  * \file galileo_e1_pcps_ambiguous_acquisition.h | ||||
|  * \file galileo_e1_pcps_ambiguous_acquisition_fpga.h | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  Galileo E1 Signals | ||||
|  * \author Marc Majoral, 2019. mmajoral(at)cttc.es | ||||
|  * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -27,7 +28,7 @@ | ||||
|  * 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_ | ||||
| @@ -60,7 +61,6 @@ public: | ||||
|  | ||||
|     inline std::string role() override | ||||
|     { | ||||
|         //   printf("top acq role\n"); | ||||
|         return role_; | ||||
|     } | ||||
|  | ||||
| @@ -69,13 +69,11 @@ public: | ||||
|      */ | ||||
|     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; | ||||
|     } | ||||
| @@ -137,27 +135,6 @@ public: | ||||
|      */ | ||||
|     void set_state(int state) override; | ||||
|  | ||||
|     /*! | ||||
|       * \brief This function is only used in the unit tests | ||||
|       */ | ||||
|      void set_single_doppler_flag(unsigned int single_doppler_flag); | ||||
|      /*! | ||||
|       * \brief This function is only used in the unit tests | ||||
|       */ | ||||
|      void read_acquisition_results(uint32_t *max_index, | ||||
|          float *max_magnitude, float *second_magnitude, uint64_t *initial_sample, uint32_t *doppler_index, uint32_t *total_fft_scaling_factor); | ||||
|  | ||||
|  | ||||
|      /*! | ||||
|       * \brief This function is only used in the unit tests | ||||
|       */ | ||||
|      void reset_acquisition(void); | ||||
|  | ||||
|      /*! | ||||
|       * \brief This function is only used in the unit tests | ||||
|       */ | ||||
|      //void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); | ||||
|  | ||||
|      /*! | ||||
|       * \brief Stop running acquisition | ||||
|       */ | ||||
| @@ -167,37 +144,25 @@ public: | ||||
|  | ||||
| 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 | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1,11 +1,12 @@ | ||||
| /*! | ||||
|  * \file galileo_e5a_pcps_acquisition.cc | ||||
|  * \file galileo_e5a_pcps_acquisition_fpga.cc | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  Galileo E5a data and pilot Signals | ||||
|  *  Galileo E5a data and pilot Signals for the FPGA | ||||
|  * \author Marc Majoral, 2019. mmajoral(at)cttc.es | ||||
|  * \author Antonio Ramos, 2018. antonio.ramos(at)cttc.es | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -26,7 +27,7 @@ | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  */  | ||||
|  | ||||
| #include "galileo_e5a_pcps_acquisition_fpga.h" | ||||
| #include "Galileo_E5a.h" | ||||
| @@ -48,48 +49,27 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf | ||||
|                                 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 = "cshort"; | ||||
|     std::string default_dump_filename = "../data/acquisition.dat"; | ||||
|  | ||||
|     DLOG(INFO) << "Role " << role; | ||||
|  | ||||
|     //item_type_ = configuration_->property(role + ".item_type", default_item_type); | ||||
|  | ||||
|  | ||||
| 	int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000); | ||||
| 	int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|  | ||||
|     float downsampling_factor = configuration_->property(role + ".downsampling_factor", 1.0); | ||||
|     acq_parameters.downsampling_factor = downsampling_factor; | ||||
|     printf("downsampling_factor = %f\n", downsampling_factor); | ||||
|     fs_in = fs_in/downsampling_factor; | ||||
|  | ||||
|     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 = configuration_->property(role + ".coherent_integration_time_ms", 1); | ||||
|     acq_parameters.sampled_ms = sampled_ms; | ||||
|     //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); | ||||
| @@ -100,15 +80,12 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf | ||||
|  | ||||
|     auto code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / GALILEO_E5A_CODE_CHIP_RATE_HZ * static_cast<double>(GALILEO_E5A_CODE_LENGTH_CHIPS))); | ||||
|     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*2)); | ||||
|     unsigned int nsamples_total = pow(2, nbits); | ||||
|     unsigned int vector_length = nsamples_total; | ||||
|     printf("code_length = %d\n", code_length); | ||||
|     printf("vector_length = %d\n", vector_length); | ||||
|     unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1); | ||||
|     printf("select queue = %d\n", select_queue_Fpga); | ||||
|     //printf("acq adapter 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); | ||||
| @@ -116,12 +93,9 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf | ||||
|     acq_parameters.samples_per_ms = nsamples_total / sampled_ms; | ||||
|     acq_parameters.samples_per_code = nsamples_total; | ||||
|  | ||||
|  | ||||
|     acq_parameters.excludelimit = static_cast<unsigned int>(ceil((1.0 / GALILEO_E5A_CODE_CHIP_RATE_HZ) * static_cast<float>(acq_parameters.fs_in))); | ||||
|  | ||||
|     //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 | ||||
|     // compute all the GALILEO E5 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time | ||||
|     // a channel is assigned) | ||||
|     auto* fft_if = new gr::fft::fft_complex(nsamples_total, true);  // Direct FFT | ||||
|     auto* code = new std::complex<float>[nsamples_total];           // buffer for the local code | ||||
| @@ -129,27 +103,20 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf | ||||
|     d_all_fft_codes_ = new lv_16sc_t[nsamples_total * GALILEO_E5A_NUMBER_OF_CODES];  // memory containing all the possible fft codes for PRN 0 to 32 | ||||
|     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_) | ||||
|                 { | ||||
|             		//printf("aaaaaaaaaaaaa\n"); | ||||
|                     strcpy(signal_, "5X"); | ||||
|                 } | ||||
|             else if (acq_pilot_) | ||||
|                 { | ||||
|             	//printf("bbbbbbbbbbbbb\n"); | ||||
|                     strcpy(signal_, "5Q"); | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|             		//printf("cccccccccccc\n"); | ||||
|                     strcpy(signal_, "5I"); | ||||
|                 } | ||||
|  | ||||
| @@ -159,14 +126,12 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf | ||||
|             for (int s = code_length; s < 2*code_length; s++) | ||||
|                 { | ||||
|                     code[s] = code[s - code_length]; | ||||
|                     //code[s] = 0; | ||||
|                 } | ||||
|  | ||||
|             // fill in zero padding | ||||
|             for (int s = 2*code_length; s < nsamples_total; s++) | ||||
|                 { | ||||
|                     code[s] = std::complex<float>(0.0, 0.0); | ||||
|                     //code[s] = 0; | ||||
|                 } | ||||
|  | ||||
|             memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total);            // copy to FFT buffer | ||||
| @@ -189,63 +154,32 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf | ||||
|                 { | ||||
|                     d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 9) - 1) / max)), | ||||
|                         static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max))); | ||||
|  | ||||
|                     //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t((2^3)*static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 6) - 1) / max)), | ||||
|                     //    (2^3)*static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 6) - 1) / max))); | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|  | ||||
|     acq_parameters.all_fft_codes = d_all_fft_codes_; | ||||
|  | ||||
|     // reference for the FPGA FFT-IFFT attenuation factor | ||||
|     acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 14); | ||||
|  | ||||
|     acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
|     channel_ = 0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = nullptr; | ||||
|  | ||||
|     // temporary buffers that we can delete | ||||
|     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() << ")"; | ||||
|  | ||||
|     acq_parameters.total_block_exp = 10; | ||||
|  | ||||
|     acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
|     //stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); | ||||
|     channel_ = 0; | ||||
|     //threshold_ = 0.0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = nullptr; | ||||
|     //printf("creating the E5A acquisition end"); | ||||
| } | ||||
|  | ||||
|  | ||||
| GalileoE5aPcpsAcquisitionFpga::~GalileoE5aPcpsAcquisitionFpga() | ||||
| { | ||||
|     //delete[] code_; | ||||
|     delete[] d_all_fft_codes_; | ||||
| } | ||||
|  | ||||
| @@ -260,33 +194,13 @@ void GalileoE5aPcpsAcquisitionFpga::stop_acquisition() | ||||
| 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_ + std::to_string(channel_) + ".pfa", 0.0); | ||||
|     // | ||||
|     //    if (pfa == 0.0) | ||||
|     //        { | ||||
|     //            pfa = configuration_->property(role_ + ".pfa", 0.0); | ||||
|     //        } | ||||
|     // | ||||
|     //    if (pfa == 0.0) | ||||
|     //        { | ||||
|     //            threshold_ = threshold; | ||||
|     //        } | ||||
|     // | ||||
|     //    else | ||||
|     //        { | ||||
|     //            threshold_ = calculate_threshold(pfa); | ||||
|     //        } | ||||
|  | ||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; | ||||
|  | ||||
|     //acquisition_->set_threshold(threshold_); | ||||
|     acquisition_fpga_->set_threshold(threshold); | ||||
| } | ||||
|  | ||||
| @@ -294,7 +208,6 @@ void GalileoE5aPcpsAcquisitionFpga::set_threshold(float 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_); | ||||
| } | ||||
|  | ||||
| @@ -302,7 +215,6 @@ void GalileoE5aPcpsAcquisitionFpga::set_doppler_max(unsigned int 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_); | ||||
| } | ||||
|  | ||||
| @@ -310,157 +222,57 @@ void GalileoE5aPcpsAcquisitionFpga::set_doppler_step(unsigned int 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); | ||||
| } | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void GalileoE5aPcpsAcquisitionFpga::set_single_doppler_flag(unsigned int single_doppler_flag) | ||||
| { | ||||
| 	acquisition_fpga_->set_single_doppler_flag(single_doppler_flag); | ||||
| } | ||||
| // this function is only used for the unit tests | ||||
| void GalileoE5aPcpsAcquisitionFpga::read_acquisition_results(uint32_t *max_index, | ||||
|     float *max_magnitude, float *second_magnitude, uint64_t *initial_sample, uint32_t *doppler_index, uint32_t *total_fft_scaling_factor) | ||||
|  | ||||
| { | ||||
| 	acquisition_fpga_->read_acquisition_results(max_index, max_magnitude, second_magnitude, | ||||
| 	        initial_sample, doppler_index, total_fft_scaling_factor); | ||||
| } | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void GalileoE5aPcpsAcquisitionFpga::reset_acquisition(void) | ||||
| { | ||||
| 	acquisition_fpga_->reset_acquisition(); | ||||
| } | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| //void GalileoE5aPcpsAcquisitionFpga::read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor) | ||||
| //{ | ||||
| //	acquisition_fpga_->read_fpga_total_scale_factor(total_scale_factor, fw_scale_factor); | ||||
| //} | ||||
|  | ||||
| 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"; | ||||
|     //        } | ||||
| 	// nothing to connect | ||||
| } | ||||
|  | ||||
|  | ||||
| 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"; | ||||
|     //        } | ||||
| 	// nothing to connect | ||||
| } | ||||
|  | ||||
|  | ||||
| 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_; | ||||
| } | ||||
|   | ||||
| @@ -1,11 +1,12 @@ | ||||
| /*! | ||||
|  * \file galileo_e5a_pcps_acquisition.h | ||||
|  * \file galileo_e5a_pcps_acquisition_fpga.h | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  Galileo E5a data and pilot Signals | ||||
|  *  Galileo E5a data and pilot Signals for the FPGA | ||||
|  * \author Marc Majoral, 2019. mmajoral(at)cttc.es | ||||
|  * \author Antonio Ramos, 2018. antonio.ramos(at)cttc.es | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -129,32 +130,18 @@ public: | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     void set_single_doppler_flag(unsigned int single_doppler_flag); | ||||
|     /*! | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     void read_acquisition_results(uint32_t *max_index, | ||||
|         float *max_magnitude, float *second_magnitude, uint64_t *initial_sample, uint32_t *doppler_index, uint32_t *total_fft_scaling_factor); | ||||
|  | ||||
|  | ||||
|     /*! | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     void reset_acquisition(void); | ||||
|  | ||||
|     /*! | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     //void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Stop running acquisition | ||||
|      */ | ||||
|     void stop_acquisition() override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief Sets the resampler latency to account it in the acquisition code delay estimation | ||||
|      */ | ||||
|     void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; | ||||
|  | ||||
| private: | ||||
|     //float calculate_threshold(float pfa); | ||||
|  | ||||
|     ConfigurationInterface* configuration_; | ||||
|  | ||||
| @@ -189,16 +176,10 @@ private: | ||||
|  | ||||
|     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_ */ | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| /*! | ||||
|  * \file gps_l1_ca_pcps_acquisition_fpga.cc | ||||
|  * \brief Adapts a PCPS acquisition block to an FPGA AcquisitionInterface | ||||
|  *  for GPS L1 C/A signals | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface | ||||
|  *  for GPS L1 C/A signals for the FPGA | ||||
|  * \authors <ul> | ||||
|  *          <li> Marc Majoral, 2018. mmajoral(at)cttc.es | ||||
|  *          <li> Marc Majoral, 2019. mmajoral(at)cttc.es | ||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  *          <li> Marc Molina, 2013. marc.molina.pena(at)gmail.com | ||||
| @@ -11,7 +11,7 @@ | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -32,7 +32,7 @@ | ||||
|  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  */  | ||||
|  | ||||
| #include "gps_l1_ca_pcps_acquisition_fpga.h" | ||||
| #include "GPS_L1_CA.h" | ||||
| @@ -67,18 +67,11 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( | ||||
| 	int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|  | ||||
|     float downsampling_factor = configuration_->property(role + ".downsampling_factor", 4.0); | ||||
|     printf("downsampling_factor = %f\n", downsampling_factor); | ||||
|     acq_parameters.downsampling_factor = downsampling_factor; | ||||
|  | ||||
|     //fs_in = fs_in/2.0; // downampling filter | ||||
|     //printf("fs_in pre downsampling = %ld\n", fs_in); | ||||
|  | ||||
|     fs_in = fs_in/downsampling_factor; | ||||
|     //printf("fs_in post downsampling = %ld\n", fs_in); | ||||
|  | ||||
|     //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); | ||||
|     if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; | ||||
|     acq_parameters.doppler_max = doppler_max_; | ||||
| @@ -86,24 +79,19 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( | ||||
|     acq_parameters.sampled_ms = sampled_ms; | ||||
|     auto code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); | ||||
|     acq_parameters.code_length = code_length; | ||||
|     //printf("acq adapter code_length = %d\n", code_length); | ||||
|     // The FPGA can only use FFT lengths that are a power of two. | ||||
|     float nbits = ceilf(log2f((float)code_length*2)); | ||||
|     unsigned int nsamples_total = pow(2, nbits); | ||||
|     unsigned int vector_length = nsamples_total; | ||||
|     //printf("acq adapter vector_length = %d\n", vector_length); | ||||
|     unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0); | ||||
|     //printf("select queue = %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); | ||||
|     //printf("acq adapter device name = %s\n", device_name.c_str()); | ||||
|     acq_parameters.device_name = device_name; | ||||
|     acq_parameters.samples_per_ms = nsamples_total / sampled_ms; | ||||
|     //printf("acq adapter samples_per_ms = %d\n", nsamples_total / sampled_ms); | ||||
|     acq_parameters.samples_per_code = nsamples_total; | ||||
|     acq_parameters.excludelimit = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / GPS_L1_CA_CODE_RATE_HZ)); | ||||
|     //printf("excludelimit = %d\n", (int) acq_parameters.excludelimit); | ||||
|  | ||||
|     // 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) | ||||
|     auto* fft_if = new gr::fft::fft_complex(vector_length, true);  // Direct FFT | ||||
| @@ -119,14 +107,12 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( | ||||
|             for (int s = code_length; s < 2*code_length; s++) | ||||
|                 { | ||||
|                     code[s] = code[s - code_length]; | ||||
|                     //code[s] = 0; | ||||
|                 } | ||||
|  | ||||
|             // fill in zero padding | ||||
|             for (int s = 2*code_length; s < nsamples_total; s++) | ||||
|                 { | ||||
|                     code[s] = std::complex<float>(0.0, 0.0); | ||||
|                     //code[s] = 0; | ||||
|                 } | ||||
|  | ||||
|             int offset = 0; | ||||
| @@ -134,19 +120,6 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( | ||||
|             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 | ||||
|                 { | ||||
| @@ -161,39 +134,17 @@ 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(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, 9) - 1) / max)), | ||||
|                         static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max))); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|             ////            // debug | ||||
|             //            char filename2[25]; | ||||
|             //            FILE *fid2; | ||||
|             //            sprintf(filename2,"fft_gps_prn%d_norm_new.txt", PRN); | ||||
|             //            fid2 = fopen(filename2, "w"); | ||||
|             //            for (unsigned int kk=0;kk< nsamples_total; kk++) | ||||
|             //                { | ||||
|             //                    fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real()); | ||||
|             //                    fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag()); | ||||
|             //                } | ||||
|             //            fclose(fid2); | ||||
|         } | ||||
|  | ||||
|     //acq_parameters | ||||
|     acq_parameters.all_fft_codes = d_all_fft_codes_; | ||||
|  | ||||
|     // temporary buffers that we can delete | ||||
|     delete[] code; | ||||
|     delete fft_if; | ||||
|     delete[] fft_codes_padded; | ||||
|  | ||||
|     acq_parameters.total_block_exp = 14; | ||||
|     // reference for the FPGA FFT-IFFT attenuation factor | ||||
|     acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 14); | ||||
|  | ||||
|     acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
| @@ -201,6 +152,12 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( | ||||
|     channel_ = 0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = nullptr; | ||||
|  | ||||
|     // temporary buffers that we can delete | ||||
|     delete[] code; | ||||
|     delete fft_if; | ||||
|     delete[] fft_codes_padded; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -226,8 +183,6 @@ 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); | ||||
| } | ||||
| @@ -274,9 +229,8 @@ void GpsL1CaPcpsAcquisitionFpga::set_local_code() | ||||
|  | ||||
| void GpsL1CaPcpsAcquisitionFpga::reset() | ||||
| { | ||||
| 	//printf("######### acq RESET called\n"); | ||||
| 	// this function starts the acquisition process | ||||
|     acquisition_fpga_->set_active(true); | ||||
|     //printf("acq reset end dddsss\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -286,33 +240,6 @@ void GpsL1CaPcpsAcquisitionFpga::set_state(int state) | ||||
| } | ||||
|  | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void GpsL1CaPcpsAcquisitionFpga::set_single_doppler_flag(unsigned int single_doppler_flag) | ||||
| { | ||||
| 	acquisition_fpga_->set_single_doppler_flag(single_doppler_flag); | ||||
| } | ||||
| // this function is only used for the unit tests | ||||
| void GpsL1CaPcpsAcquisitionFpga::read_acquisition_results(uint32_t *max_index, | ||||
|     float *max_magnitude, float *second_magnitude, uint64_t *initial_sample, uint32_t *doppler_index, uint32_t *total_fft_scaling_factor) | ||||
|  | ||||
| { | ||||
| 	acquisition_fpga_->read_acquisition_results(max_index, max_magnitude, second_magnitude, | ||||
| 	        initial_sample, doppler_index, total_fft_scaling_factor); | ||||
| } | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void GpsL1CaPcpsAcquisitionFpga::reset_acquisition(void) | ||||
| { | ||||
| 	acquisition_fpga_->reset_acquisition(); | ||||
| } | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| //void GpsL1CaPcpsAcquisitionFpga::read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor) | ||||
| //{ | ||||
| //	acquisition_fpga_->read_fpga_total_scale_factor(total_scale_factor, fw_scale_factor); | ||||
| //} | ||||
|  | ||||
|  | ||||
| void GpsL1CaPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     // nothing to connect | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| /*! | ||||
|  * \file gps_l1_ca_pcps_acquisition_fpga.h | ||||
|  * \brief Adapts a PCPS acquisition block that uses the FPGA to | ||||
|  *  an AcquisitionInterface for GPS L1 C/A signals | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface | ||||
|  *  for GPS L1 C/A signals for the FPGA | ||||
|  * \authors <ul> | ||||
|  *          <li> Marc Majoral, 2018. mmajoral(at)cttc.es | ||||
|  *          <li> Marc Majoral, 2019. mmajoral(at)cttc.es | ||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  *          <li> Marc Molina, 2013. marc.molina.pena(at)gmail.com | ||||
| @@ -11,7 +11,7 @@ | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -32,7 +32,7 @@ | ||||
|  * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  */  | ||||
|  | ||||
| #ifndef GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FPGA_H_ | ||||
| #define GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FPGA_H_ | ||||
| @@ -135,26 +135,6 @@ public: | ||||
|      */ | ||||
|     void set_state(int state) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     void set_single_doppler_flag(unsigned int single_doppler_flag); | ||||
|     /*! | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     void read_acquisition_results(uint32_t *max_index, | ||||
|         float *max_magnitude, float *second_magnitude, uint64_t *initial_sample, uint32_t *doppler_index, uint32_t *total_fft_scaling_factor); | ||||
|  | ||||
|     /*! | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     void reset_acquisition(void); | ||||
|  | ||||
|     /*! | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     //void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Stop running acquisition | ||||
|      */ | ||||
|   | ||||
| @@ -1,14 +1,15 @@ | ||||
| /*! | ||||
|  * \file gps_l5i pcps_acquisition.cc | ||||
|  * \file gps_l5i pcps_acquisition_fpga.cc | ||||
|  * \brief Adapts a PCPS acquisition block to an Acquisition Interface for | ||||
|  *  GPS L5i signals | ||||
|  *  GPS L5i signals for the FPGA | ||||
|  * \authors <ul> | ||||
|  *          <li> Marc Majoral, 2017. mmajoral(at)cttc.es | ||||
|  *          <li> Javier Arribas, 2017. jarribas(at)cttc.es | ||||
|  *          </ul> | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2017  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -52,16 +53,12 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( | ||||
|                                 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 = "cshort"; | ||||
|     std::string default_dump_filename = "./data/acquisition.dat"; | ||||
|  | ||||
|     LOG(INFO) << "role " << role; | ||||
|  | ||||
|     //item_type_ = configuration_->property(role + ".item_type", default_item_type); | ||||
|  | ||||
| 	int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||
| 	int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|  | ||||
| @@ -72,29 +69,12 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( | ||||
|  | ||||
|  | ||||
|     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 ------------------------- | ||||
|     auto code_length = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / (GPS_L5I_CODE_RATE_HZ / static_cast<double>(GPS_L5I_CODE_LENGTH_CHIPS)))); | ||||
|     acq_parameters.code_length = code_length; | ||||
| @@ -103,10 +83,6 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( | ||||
|     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("code_length = %d\n", (int)  code_length); | ||||
|     printf("vector length = %d\n", (int) vector_length); | ||||
|     printf("select queue = %d\n", select_queue_Fpga); | ||||
|     printf("sampled_ms = %d\n", sampled_ms); | ||||
|     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); | ||||
| @@ -114,40 +90,29 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( | ||||
|     acq_parameters.samples_per_ms = nsamples_total/sampled_ms; | ||||
|     acq_parameters.samples_per_code = nsamples_total; | ||||
|  | ||||
|     //acq_parameters.excludelimit = static_cast<unsigned int>(std::round(static_cast<double>(fs_in) / GPS_L5i_CODE_RATE_HZ)); | ||||
|     acq_parameters.excludelimit = static_cast<unsigned int>(ceil((1.0 / GPS_L5I_CODE_RATE_HZ) * static_cast<float>(acq_parameters.fs_in))); | ||||
|  | ||||
|     //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(nsamples_total, true);  // Direct FFT | ||||
|     //printf("L5 ACQ CLASS MID 02\n"); | ||||
|     std::complex<float>* code = new gr_complex[nsamples_total]; | ||||
|     //printf("L5 ACQ CLASS MID 03\n"); | ||||
|     auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); | ||||
|     //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 < 2*code_length; s++) | ||||
|             { | ||||
|                 code[s] = code[s - code_length]; | ||||
|                 //code[s] = 0; | ||||
|             } | ||||
|  | ||||
|         for (int s = 2*code_length; s < nsamples_total; s++) | ||||
|             { | ||||
|         		// fill in zero padding | ||||
|                 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 | ||||
| @@ -167,76 +132,29 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( | ||||
|             } | ||||
|         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, 9) - 1) / max)), | ||||
|                     static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max))); | ||||
|             } | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     //printf("L5 ACQ CLASS MID 2\n"); | ||||
|  | ||||
|     //acq_parameters | ||||
|     acq_parameters.all_fft_codes = d_all_fft_codes_; | ||||
|  | ||||
|     // reference for the FPGA FFT-IFFT attenuation factor | ||||
|     acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 14); | ||||
|  | ||||
|     acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
|     channel_ = 0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = nullptr; | ||||
|  | ||||
|     // temporary buffers that we can delete | ||||
|     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() << ")"; | ||||
|  | ||||
|     acq_parameters.total_block_exp = 10; | ||||
|  | ||||
|     acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); | ||||
|     DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; | ||||
|  | ||||
|     //    stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); | ||||
|     //    DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; | ||||
|     // | ||||
|     //    if (item_type_.compare("cbyte") == 0) | ||||
|     //        { | ||||
|     //            cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); | ||||
|     //            float_to_complex_ = gr::blocks::float_to_complex::make(); | ||||
|     //        } | ||||
|  | ||||
|     channel_ = 0; | ||||
|     //    threshold_ = 0.0; | ||||
|     doppler_step_ = 0; | ||||
|     gnss_synchro_ = nullptr; | ||||
|     //printf("L5 ACQ CLASS FINISHED\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -263,25 +181,6 @@ void GpsL5iPcpsAcquisitionFpga::set_channel(unsigned int channel) | ||||
|  | ||||
| void GpsL5iPcpsAcquisitionFpga::set_threshold(float threshold) | ||||
| { | ||||
|     //    float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0); | ||||
|     // | ||||
|     //    if (pfa == 0.0) | ||||
|     //        { | ||||
|     //            pfa = configuration_->property(role_ + ".pfa", 0.0); | ||||
|     //        } | ||||
|     //    if (pfa == 0.0) | ||||
|     //        { | ||||
|     //            threshold_ = threshold; | ||||
|     //        } | ||||
|     //    else | ||||
|     //        { | ||||
|     //            threshold_ = calculate_threshold(pfa); | ||||
|     //        } | ||||
|  | ||||
|     //    DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; | ||||
|  | ||||
|     // the .pfa parameter and the threshold calculation is only used for the CFAR algorithm. | ||||
|     // We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such. | ||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; | ||||
|     acquisition_fpga_->set_threshold(threshold); | ||||
| } | ||||
| @@ -293,7 +192,6 @@ void GpsL5iPcpsAcquisitionFpga::set_doppler_max(unsigned int 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) | ||||
| @@ -337,126 +235,20 @@ 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; | ||||
| //} | ||||
|  | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void GpsL5iPcpsAcquisitionFpga::set_single_doppler_flag(unsigned int single_doppler_flag) | ||||
| { | ||||
| 	acquisition_fpga_->set_single_doppler_flag(single_doppler_flag); | ||||
| } | ||||
| // this function is only used for the unit tests | ||||
| void GpsL5iPcpsAcquisitionFpga::read_acquisition_results(uint32_t *max_index, | ||||
|     float *max_magnitude, float *second_magnitude, uint64_t *initial_sample, uint32_t *doppler_index, uint32_t *total_fft_scaling_factor) | ||||
|  | ||||
| { | ||||
| 	acquisition_fpga_->read_acquisition_results(max_index, max_magnitude, second_magnitude, | ||||
| 	        initial_sample, doppler_index, total_fft_scaling_factor); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void GpsL5iPcpsAcquisitionFpga::reset_acquisition(void) | ||||
| { | ||||
| 	acquisition_fpga_->reset_acquisition(); | ||||
| } | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| //void GpsL5iPcpsAcquisitionFpga::read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor) | ||||
| //{ | ||||
| //	acquisition_fpga_->read_fpga_total_scale_factor(total_scale_factor, fw_scale_factor); | ||||
| //} | ||||
|  | ||||
| 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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,14 +1,15 @@ | ||||
| /*! | ||||
|  * \file GPS_L5i_PCPS_Acquisition.h | ||||
|  * \file GPS_L5i_PCPS_Acquisition_fpga.h | ||||
|  * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for | ||||
|  *  GPS L5i signals | ||||
|  *  GPS L5i signals for the FPGA | ||||
|  * \authors <ul> | ||||
|  *          <li> Marc Majoral, 2019. mmajoral(at)cttc.es | ||||
|  *          <li> Javier Arribas, 2017. jarribas(at)cttc.es | ||||
|  *          </ul> | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2017  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -135,27 +136,6 @@ public: | ||||
|      */ | ||||
|     void set_state(int state) override; | ||||
|  | ||||
|     /*! | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     void set_single_doppler_flag(unsigned int single_doppler_flag); | ||||
|     /*! | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     void read_acquisition_results(uint32_t *max_index, | ||||
|         float *max_magnitude, float *second_magnitude, uint64_t *initial_sample, uint32_t *doppler_index, uint32_t *total_fft_scaling_factor); | ||||
|  | ||||
|  | ||||
|     /*! | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     void reset_acquisition(void); | ||||
|  | ||||
|     /*! | ||||
|      * \brief This function is only used in the unit tests | ||||
|      */ | ||||
|     //void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); | ||||
|  | ||||
|     /*! | ||||
|      * \brief Stop running acquisition | ||||
|      */ | ||||
| @@ -165,7 +145,6 @@ public: | ||||
|  | ||||
| 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_; | ||||
| @@ -182,7 +161,6 @@ private: | ||||
|     unsigned int doppler_step_; | ||||
|     unsigned int max_dwells_; | ||||
|     int64_t fs_in_; | ||||
|     //long if_; | ||||
|     bool dump_; | ||||
|     bool blocking_; | ||||
|     std::string dump_filename_; | ||||
|   | ||||
| @@ -1,12 +1,8 @@ | ||||
| /*! | ||||
|  * \file pcps_acquisition_fpga.cc | ||||
|  * \brief This class implements a Parallel Code Phase Search Acquisition in the FPGA | ||||
|  * | ||||
|  * Note: The CFAR algorithm is not implemented in the FPGA. | ||||
|  * Note 2: The bit transition flag is not implemented in the FPGA | ||||
|  * | ||||
|  * \brief This class implements a Parallel Code Phase Search Acquisition for the FPGA | ||||
|  * \authors <ul> | ||||
|  *          <li> Marc Majoral, 2017. mmajoral(at)cttc.cat | ||||
|  *          <li> Marc Majoral, 2019. mmajoral(at)cttc.es | ||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  *          <li> Marc Molina, 2013. marc.molina.pena@gmail.com | ||||
| @@ -15,7 +11,7 @@ | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2017  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -33,10 +29,10 @@ | ||||
|  * 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/>. | ||||
|  * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  */  | ||||
|  | ||||
|  | ||||
| #include "pcps_acquisition_fpga.h" | ||||
| @@ -60,14 +56,12 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_) : gr::block( | ||||
|                                                                           gr::io_signature::make(0, 0, 0), | ||||
|                                                                           gr::io_signature::make(0, 0, 0)) | ||||
| { | ||||
|     //   printf("acq constructor start\n"); | ||||
|     this->message_port_register_out(pmt::mp("events")); | ||||
|  | ||||
|     acq_parameters = std::move(conf_); | ||||
|     d_sample_counter = 0ULL;  // 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.samples_per_code; | ||||
|     d_mag = 0; | ||||
|     d_input_power = 0.0; | ||||
| @@ -77,58 +71,32 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_) : gr::block( | ||||
|     d_test_statistics = 0.0; | ||||
|     d_channel = 0U; | ||||
|     d_gnss_synchro = nullptr; | ||||
|     d_single_doppler_flag = false; | ||||
|  | ||||
|     d_downsampling_factor = acq_parameters.downsampling_factor; | ||||
|     //printf("CONSTRUCTOR downsampling_factor = %d\n", (int) d_downsampling_factor); | ||||
|     d_select_queue_Fpga = acq_parameters.select_queue_Fpga; | ||||
|     //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); | ||||
|  | ||||
|  | ||||
|     d_total_block_exp = acq_parameters.total_block_exp; | ||||
|  | ||||
|     // 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, acq_parameters.excludelimit); | ||||
|  | ||||
|     //    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; | ||||
| @@ -139,32 +107,20 @@ void pcps_acquisition_fpga::init() | ||||
|     d_mag = 0.0; | ||||
|     d_input_power = 0.0; | ||||
|  | ||||
|     if (d_single_doppler_flag == 1) | ||||
|     { | ||||
|     	d_num_doppler_bins = 1; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|     	d_num_doppler_bins = static_cast<uint32_t>(std::ceil(static_cast<double>(static_cast<int32_t>(acq_parameters.doppler_max) - static_cast<int32_t>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step))) + 1; | ||||
|     } | ||||
|     	//printf("acq gnuradioblock doppler_max = %lu\n", (unsigned long) static_cast<int32_t>(acq_parameters.doppler_max)); | ||||
|     //printf("acq gnuradioblock doppler_step = %lu\n", (unsigned long) d_doppler_step); | ||||
|     //printf("acq gnuradioblock d_num_doppler_bins = %lu\n", (unsigned long) d_num_doppler_bins); | ||||
|     acquisition_fpga->init(); | ||||
|     //  printf("acq init end\n"); | ||||
|   	d_num_doppler_bins = static_cast<uint32_t>(std::ceil(static_cast<double>(static_cast<int32_t>(acq_parameters.doppler_max) - static_cast<int32_t>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step))) + 1; | ||||
|  | ||||
|   	acquisition_fpga->init(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void pcps_acquisition_fpga::set_state(int32_t state) | ||||
| { | ||||
|     //   printf("acq set state start\n"); | ||||
|     d_state = state; | ||||
|     if (d_state == 1) | ||||
|         { | ||||
|             d_gnss_synchro->Acq_delay_samples = 0.0; | ||||
|             d_gnss_synchro->Acq_doppler_hz = 0.0; | ||||
|             d_gnss_synchro->Acq_samplestamp_samples = 0; | ||||
|             //d_well_count = 0; | ||||
|             d_mag = 0.0; | ||||
|             d_input_power = 0.0; | ||||
|             d_test_statistics = 0.0; | ||||
| @@ -177,14 +133,12 @@ void pcps_acquisition_fpga::set_state(int32_t state) | ||||
|         { | ||||
|             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 | ||||
|     // Declare positive acquisition using a message port | ||||
|     //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL | ||||
|     DLOG(INFO) << "positive acquisition" | ||||
|                << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN | ||||
| @@ -196,17 +150,13 @@ void pcps_acquisition_fpga::send_positive_acquisition() | ||||
|                << ", magnitude " << d_mag | ||||
|                << ", input signal power " << d_input_power; | ||||
|  | ||||
|     //printf("acq sending positive acquisition\n"); | ||||
|     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 | ||||
|     // Declare negative acquisition using a message port | ||||
|     DLOG(INFO) << "negative acquisition" | ||||
|                << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN | ||||
|                << ", sample_stamp " << d_sample_counter | ||||
| @@ -217,16 +167,13 @@ void pcps_acquisition_fpga::send_negative_acquisition() | ||||
|                << ", magnitude " << d_mag | ||||
|                << ", input signal power " << d_input_power; | ||||
|  | ||||
|     //printf("acq sending negative acquisition\n"); | ||||
|     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 | ||||
| @@ -234,7 +181,6 @@ void pcps_acquisition_fpga::set_active(bool active) | ||||
|     float firstpeak = 0.0; | ||||
|     float secondpeak = 0.0; | ||||
|     uint32_t total_block_exp; | ||||
|     //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; | ||||
| @@ -255,136 +201,22 @@ void pcps_acquisition_fpga::set_active(bool active) | ||||
|  | ||||
|     float temp_d_input_power; | ||||
|  | ||||
|     // debug | ||||
|     //acquisition_fpga->block_samples(); | ||||
|  | ||||
|  | ||||
|    // while(1) | ||||
|    //{ | ||||
|  | ||||
|     //printf("######### acq ENTERING SET ACTIVE\n"); | ||||
|  | ||||
|     // run loop in hw | ||||
|     //printf("LAUNCH ACQ\n"); | ||||
|     //printf("acq lib d_num_doppler_bins = %d\n", d_num_doppler_bins); | ||||
|     //printf("writing config for channel %d -----------------------------------------\n", (int) d_channel); | ||||
|  | ||||
|  | ||||
|     //printf("d_downsampling_factor = %f\n", d_downsampling_factor); | ||||
|  | ||||
|     //printf("acq_parameters.code_length = %d\n", (int) acq_parameters.code_length); | ||||
|         // debug | ||||
| //        if (acq_parameters.code_length == 12500) | ||||
| //        { | ||||
| //        	acquisition_fpga->configure_acquisition_debug(); | ||||
| //        	acquisition_fpga->set_doppler_sweep(d_num_doppler_bins); | ||||
| //        	acquisition_fpga->write_local_code(); | ||||
| //        	acquisition_fpga->set_block_exp(d_total_block_exp); | ||||
| // | ||||
| //        	acquisition_fpga->run_acquisition(); | ||||
| //            acquisition_fpga->read_acquisition_results(&indext, &firstpeak, &secondpeak, &initial_sample, &d_input_power, &d_doppler_index, &total_block_exp); | ||||
| // | ||||
| //        	doppler = 0; | ||||
| //        	d_test_statistics = 0; | ||||
| //        } | ||||
| //        else | ||||
| //        { | ||||
|  | ||||
|  | ||||
|  | ||||
|     acquisition_fpga->configure_acquisition(); | ||||
|     acquisition_fpga->set_doppler_sweep(d_num_doppler_bins); | ||||
|  | ||||
|  | ||||
|  | ||||
|     //printf("d_num_doppler_bins = %d\n", (int) d_num_doppler_bins); | ||||
|     acquisition_fpga->write_local_code(); | ||||
|  | ||||
|  | ||||
|  | ||||
|     //acquisition_fpga->set_doppler_sweep(2); | ||||
|     //printf("acq lib going to launch acquisition\n"); | ||||
|     acquisition_fpga->set_block_exp(d_total_block_exp); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     //printf("running acq for channel %d\n", (int) d_channel); | ||||
|  | ||||
|     acquisition_fpga->run_acquisition(); | ||||
|     //printf("acq lib going to read the acquisition results\n"); | ||||
|     //read_acquisition_results(&indext, &firstpeak, &secondpeak, &initial_sample, &d_input_power, &d_doppler_index); | ||||
|  | ||||
|  | ||||
|     //printf("reading results for channel %d\n", (int) d_channel); | ||||
|     acquisition_fpga->read_acquisition_results(&indext, &firstpeak, &secondpeak, &initial_sample, &d_input_power, &d_doppler_index, &total_block_exp); | ||||
|  | ||||
|  | ||||
|  | ||||
|     //printf("returned d_doppler_index = %d\n", d_doppler_index); | ||||
|  | ||||
|     //printf("gnuradio block : d_total_block_exp = %d total_block_exp = %d\n", (int) d_total_block_exp, (int) total_block_exp); | ||||
|  | ||||
|     //printf("d_fft_size = %d = %d\n", d_fft_size, acq_parameters.samples_per_code); | ||||
|     //printf("indext = %d\n", (int) indext); | ||||
|     //printf("initial_sample = %d\n", (int) initial_sample); | ||||
|     //printf("firstpeak = %d\n", (int) firstpeak); | ||||
|     //printf("secondpeak = %d\n", (int) secondpeak); | ||||
|     //printf("total_block_exp = %d\n", (int) total_block_exp); | ||||
| //    if (total_block_exp == 11) | ||||
| //    { | ||||
| //    	printf("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n"); | ||||
| //    	getchar(); | ||||
| // | ||||
| //    } | ||||
| //    if (total_block_exp > d_total_block_exp) | ||||
| //    { | ||||
| //    	usleep(5000000); | ||||
| //    	acquisition_fpga->read_acquisition_results(&indext, &firstpeak, &secondpeak, &initial_sample, &d_input_power, &d_doppler_index, &total_block_exp); | ||||
| //        printf("second time d_fft_size = %d = %d", d_fft_size, acq_parameters.samples_per_code); | ||||
| //        printf("second time indext = %d\n", (int) indext); | ||||
| //        printf("second time initial_sample = %d\n", (int) initial_sample); | ||||
| //        printf("second time firstpeak = %d\n", (int) firstpeak); | ||||
| //        printf("second time secondpeak = %d\n", (int) secondpeak); | ||||
| //        printf("second time total_block_exp = %d\n", (int) total_block_exp); | ||||
| //    } | ||||
|  | ||||
|     if (total_block_exp > d_total_block_exp) | ||||
|     { | ||||
|     	printf("changing blk exp..... d_total_block_exp = %d total_block_exp = %d chan = %d\n", d_total_block_exp, total_block_exp, d_channel); | ||||
|     	//getchar(); | ||||
|     	// if the attenuation factor of the FPGA FFT-IFFT is smaller than the reference attenuation factor then we need to update the reference attenuation factor | ||||
|     	std::cout << "changing blk exp..... d_total_block_exp = " << d_total_block_exp << " total_block_exp = " << total_block_exp << " chan = " << d_channel << std::endl; | ||||
|     	d_total_block_exp = total_block_exp; | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     //printf("end channel %d -----------------------------------------------------\n", (int) d_channel); | ||||
|     //printf("READ ACQ RESULTS\n"); | ||||
|  | ||||
|     // debug | ||||
|     //acquisition_fpga->unblock_samples(); | ||||
|  | ||||
|  | ||||
|     //usleep(5000000); | ||||
|     //} // end while test | ||||
|  | ||||
|     //int32_t doppler; | ||||
|  | ||||
|     // NEW SATELLITE DETECTION ALGORITHM STARTS HERE ---------------------------------------------------- | ||||
|  | ||||
|  | ||||
|  | ||||
| 	if (d_single_doppler_flag == false) | ||||
| 	{ | ||||
| 		doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * (d_doppler_index - 1); | ||||
| 		//doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * (d_doppler_index); // this is the wrong one | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		doppler = static_cast<int32_t>(acq_parameters.doppler_max); | ||||
| 	} | ||||
| 	doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * (d_doppler_index - 1); | ||||
|  | ||||
| 	if (secondpeak > 0) | ||||
| 	{ | ||||
| @@ -395,40 +227,6 @@ void pcps_acquisition_fpga::set_active(bool active) | ||||
| 		d_test_statistics = 0.0; | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //    // OLD SATELLITE DETECTION ALGORITHM STARTS HERE ---------------------------------------------------- | ||||
| // | ||||
| //    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; | ||||
| //	if (d_single_doppler_flag == false) | ||||
| //	{ | ||||
| //		doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * (d_doppler_index - 1); | ||||
| //		//doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * (d_doppler_index); // this is the wrong one | ||||
| //	} | ||||
| //	else | ||||
| //	{ | ||||
| //		doppler = static_cast<int32_t>(acq_parameters.doppler_max); | ||||
| //	} | ||||
| //    //d_gnss_synchro->Acq_delay_samples = static_cast<double>(2*(indext % (2*acq_parameters.samples_per_code))); | ||||
| // | ||||
| // | ||||
| //    //printf("acq gnuradioblock doppler = %d\n", doppler); | ||||
| // | ||||
| //	// END OF OLD SATELLITE ALGORITHM -------------------------------------------------------------------- | ||||
|  | ||||
|     d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); | ||||
|     d_sample_counter = initial_sample; | ||||
|  | ||||
| @@ -437,86 +235,27 @@ void pcps_acquisition_fpga::set_active(bool active) | ||||
|     	if (d_downsampling_factor > 1) | ||||
|     	{ | ||||
|  | ||||
|     		//printf("yes here\n"); | ||||
|     		//d_gnss_synchro->Acq_delay_samples = static_cast<double>(d_downsampling_factor*(indext % acq_parameters.samples_per_code)); | ||||
|     		d_gnss_synchro->Acq_delay_samples = static_cast<double>(d_downsampling_factor*(indext)); | ||||
|     		//d_gnss_synchro->Acq_samplestamp_samples = d_downsampling_factor*d_sample_counter - 81*0.25*d_downsampling_factor; // delay due to the downsampling filter in the acquisition | ||||
|     		d_gnss_synchro->Acq_samplestamp_samples = d_downsampling_factor*d_sample_counter - 44; //33; //41; //+ 81*0.5; // delay due to the downsampling filter in the acquisition | ||||
|     		//d_gnss_synchro->Acq_samplestamp_samples = d_downsampling_factor*d_sample_counter - 81/d_downsampling_factor; // delay due to the downsampling filter in the acquisition | ||||
|     		//d_gnss_synchro->Acq_delay_samples = static_cast<double>(2*(indext % acq_parameters.samples_per_code)); | ||||
|     		//d_gnss_synchro->Acq_delay_samples = static_cast<double>(2*(indext)); | ||||
|     		//d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter*2 - 81; | ||||
|         	//d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code); | ||||
|         	//d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; | ||||
|  | ||||
|     	} | ||||
|     	else | ||||
|     	{ | ||||
|     		//printf("xxxxxxxxxxxxxxxx no here\n"); | ||||
|         	//d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code); | ||||
|         	d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext); | ||||
|         	d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;  // delay due to the downsampling filter in the acquisition | ||||
|         	//d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter - 40;  // delay due to the downsampling filter in the acquisition | ||||
|         	//d_gnss_synchro->Acq_samplestamp_samples = d_downsampling_factor*d_sample_counter - 81*0.5*d_downsampling_factor; | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|     	//d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code); | ||||
|     	d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext); | ||||
|     	d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;  // delay due to the downsampling filter in the acquisition | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     //d_gnss_synchro->Acq_samplestamp_samples = 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 | ||||
|  | ||||
| //    // OLD SATELLITE DETECTION ALGORITHM STARTS HERE AGAIN ----------------------------------------------- | ||||
| // | ||||
| //    d_test_statistics = (d_mag / d_input_power);                 //* correction_factor; | ||||
| // | ||||
| //    // END OF OLD SATELLITE ALGORITHM AGAIN -------------------------------------------------------------------- | ||||
|  | ||||
|  | ||||
|  | ||||
|     // 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("##### firstpeak =%f\n",firstpeak); | ||||
| //                        printf("##### secondpeak =%f\n",secondpeak); | ||||
| //                        printf("##### d_gnss_synchro->Acq_delay_samples = %d\n",(int) d_gnss_synchro->Acq_delay_samples); | ||||
| //                        printf("##### d_gnss_synchro->Acq_samplestamp_samples = %d\n",(int) d_gnss_synchro->Acq_samplestamp_samples); | ||||
|             send_positive_acquisition(); | ||||
|             d_state = 0;  // Positive acquisition | ||||
|  | ||||
|             //printf("acq POSITIVE ACQ d_fft_size = %d = %d\n", d_fft_size, acq_parameters.samples_per_code); | ||||
|             //printf("acq POSITIVE ACQ d_gnss_synchro->Acq_delay_samples = %f\n: ",d_gnss_synchro->Acq_delay_samples); | ||||
|             //printf("acq POSITIVE ACQ d_gnss_synchro->Acq_samplestamp_samples = %d\n", (unsigned int) d_gnss_synchro->Acq_samplestamp_samples); | ||||
|             //printf("acq POSITIVE ACQ d_gnss_synchro->Acq_doppler_hz = %f\n", d_gnss_synchro->Acq_doppler_hz); | ||||
|             //printf("acq POSITIVE ACQ d_gnss_synchro->PRN = %d\n", (int) d_gnss_synchro->PRN); | ||||
|         } | ||||
|     else | ||||
|         { | ||||
| @@ -524,9 +263,6 @@ void pcps_acquisition_fpga::set_active(bool active) | ||||
|             d_active = false; | ||||
|             send_negative_acquisition(); | ||||
|         } | ||||
|  | ||||
|     //printf("######### acq LEAVING SET ACTIVE\n"); | ||||
|     //printf("acq set active end\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -534,71 +270,13 @@ int pcps_acquisition_fpga::general_work(int noutput_items __attribute__((unused) | ||||
|     gr_vector_int& ninput_items, gr_vector_const_void_star& input_items, | ||||
|     gr_vector_void_star& output_items __attribute__((unused))) | ||||
| { | ||||
| 	//printf("ACQ GENERAL WORK CALLED\n"); | ||||
|     // the general work is not used with the acquisition that uses the FPGA | ||||
|     return noutput_items; | ||||
| } | ||||
|  | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void pcps_acquisition_fpga::set_single_doppler_flag(unsigned int single_doppler_flag) | ||||
| { | ||||
| 	acquisition_fpga->set_single_doppler_flag(single_doppler_flag); | ||||
| 	d_single_doppler_flag = true; | ||||
| } | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void pcps_acquisition_fpga::read_acquisition_results(uint32_t *max_index, | ||||
|     float *max_magnitude, float *second_magnitude, uint64_t *initial_sample, uint32_t *doppler_index, uint32_t *total_fft_scaling_factor) | ||||
| { | ||||
| 	float input_power; // not used | ||||
| 	uint32_t max_index_tmp; | ||||
| 	uint64_t initial_sample_tmp; | ||||
|     acquisition_fpga->read_acquisition_results(&max_index_tmp, max_magnitude, second_magnitude, &initial_sample_tmp, &input_power, doppler_index, total_fft_scaling_factor); | ||||
|  | ||||
|  | ||||
|     if (d_select_queue_Fpga == 0) | ||||
|     { | ||||
|     	if (d_downsampling_factor > 1) | ||||
|     	{ | ||||
|     		//printf("yes here\n"); | ||||
|     		*max_index = static_cast<double>(d_downsampling_factor*(max_index_tmp)); | ||||
|     		//d_gnss_synchro->Acq_samplestamp_samples = d_downsampling_factor*d_sample_counter - 81*0.25*d_downsampling_factor; // delay due to the downsampling filter in the acquisition | ||||
|     		*initial_sample = (initial_sample_tmp)*d_downsampling_factor - 44; //33; //41; //+ 81*0.5; // delay due to the downsampling filter in the acquisition | ||||
|     		//d_gnss_synchro->Acq_samplestamp_samples = d_downsampling_factor*d_sample_counter - 81/d_downsampling_factor; // delay due to the downsampling filter in the acquisition | ||||
|     		//d_gnss_synchro->Acq_delay_samples = static_cast<double>(2*(indext % acq_parameters.samples_per_code)); | ||||
|     		//d_gnss_synchro->Acq_delay_samples = static_cast<double>(2*(indext)); | ||||
|     		//d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter*2 - 81; | ||||
|         	//d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code); | ||||
|         	//d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; | ||||
|  | ||||
|     	} | ||||
|     	else | ||||
|     	{ | ||||
|     		//printf("xxxxxxxxxxxxxxxx no here\n"); | ||||
|     		//max_index = static_cast<double>(indext % acq_parameters.samples_per_code); | ||||
|     		//initial_sample = d_sample_counter;  // 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_downsampling_factor*d_sample_counter - 81*0.5*d_downsampling_factor; | ||||
|         } | ||||
|     } | ||||
| //    printf("gnuradioblock acq samplestamp = %d\n", (int) *initial_sample); | ||||
| //    else | ||||
| //    { | ||||
| //    	d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code); | ||||
| //    	d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;  // delay due to the downsampling filter in the acquisition | ||||
| //    } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //	acquisition_fpga->read_acquisition_results(max_index, max_magnitude, | ||||
| //	        initial_sample, power_sum, doppler_index); | ||||
| } | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void pcps_acquisition_fpga::reset_acquisition(void) | ||||
| { | ||||
| 	// this function triggers a HW reset of the FPGA PL. | ||||
| 	acquisition_fpga->reset_acquisition(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,26 +1,14 @@ | ||||
| /*! | ||||
|  * \file pcps_acquisition_fpga.h | ||||
|  * \brief This class implements a Parallel Code Phase Search Acquisition in the FPGA. | ||||
|  * \brief This class implements a Parallel Code Phase Search Acquisition for the FPGA | ||||
|  * | ||||
|  * Note: The CFAR algorithm is not implemented in the FPGA. | ||||
|  * Note 2: The bit transition flag is not implemented in the FPGA | ||||
|  * | ||||
|  *  Acquisition strategy (Kay Borre book + CFAR threshold). | ||||
|  *  <ol> | ||||
|  *  <li> Compute the input signal power estimation | ||||
|  *  <li> Doppler serial search loop | ||||
|  *  <li> Perform the FFT-based circular convolution (parallel time search) | ||||
|  *  <li> Record the maximum peak and the associated synchronization parameters | ||||
|  *  <li> Compute the test statistics and compare to the threshold | ||||
|  *  <li> Declare positive or negative acquisition using a message queue | ||||
|  *  </ol> | ||||
|  * | ||||
|  * Kay Borre book: K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, | ||||
|  * "A Software-Defined GPS and Galileo Receiver. A Single-Frequency | ||||
|  * Approach", Birkhauser, 2007. pp 81-84 | ||||
|  * | ||||
|  * \authors <ul> | ||||
|  *          <li> Marc Majoral, 2017. mmajoral(at)cttc.cat | ||||
|  *          <li> Marc Majoral, 2019. mmajoral(at)cttc.es | ||||
|  *          <li> Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com | ||||
|  *          <li> Marc Molina, 2013. marc.molina.pena@gmail.com | ||||
| @@ -30,7 +18,7 @@ | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -51,7 +39,7 @@ | ||||
|  * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  */  | ||||
|  | ||||
| #ifndef GNSS_SDR_PCPS_ACQUISITION_FPGA_H_ | ||||
| #define GNSS_SDR_PCPS_ACQUISITION_FPGA_H_ | ||||
| @@ -122,15 +110,8 @@ 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; | ||||
|  | ||||
|     float d_downsampling_factor; | ||||
|     uint32_t d_select_queue_Fpga; | ||||
|     bool d_single_doppler_flag; | ||||
|  | ||||
|     uint32_t d_total_block_exp; | ||||
|  | ||||
| @@ -145,9 +126,7 @@ 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"); | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
| @@ -155,9 +134,7 @@ public: | ||||
|      */ | ||||
|     inline uint32_t mag() const | ||||
|     { | ||||
|         //   printf("acq dmag start\n"); | ||||
|         return d_mag; | ||||
|         //   printf("acq dmag end\n"); | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
| @@ -238,19 +215,7 @@ public: | ||||
|         gr_vector_void_star& output_items); | ||||
|  | ||||
|     /*! | ||||
|      * \brief This function is only used for the unit tests | ||||
|      */ | ||||
|     void set_single_doppler_flag(unsigned int single_doppler_flag); | ||||
|  | ||||
|     /*! | ||||
|      * \brief This funciton is only used for the unit tests | ||||
|      */ | ||||
|     void read_acquisition_results(uint32_t *max_index, | ||||
|         float *max_magnitude, float *second_magnitude, uint64_t *initial_sample, uint32_t *doppler_index, uint32_t *total_fft_scaling_factor); | ||||
|  | ||||
|  | ||||
|     /*! | ||||
|      * \brief This funciton is only used for the unit tests | ||||
|      * \brief This funciton triggers a HW reset of the FPGA PL. | ||||
|      */ | ||||
|     void reset_acquisition(void); | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * \file fpga_acquisition.cc | ||||
|  * \brief High optimized FPGA vector correlator class | ||||
|  * \authors <ul> | ||||
|  *          <li> Marc Majoral, 2018. mmajoral(at)cttc.cat | ||||
|  *          <li> Marc Majoral, 2019. mmajoral(at)cttc.cat | ||||
|  *          </ul> | ||||
|  * | ||||
|  * Class that controls and executes a high optimized acquisition HW | ||||
| @@ -31,7 +31,7 @@ | ||||
|  * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  */  | ||||
|  | ||||
| #include "fpga_acquisition.h" | ||||
| #include "GPS_L1_CA.h" | ||||
| @@ -42,10 +42,9 @@ | ||||
| #include <sys/mman.h>  // libraries used by the GIPO | ||||
| #include <utility> | ||||
|  | ||||
| #include <unistd.h> // for the usleep function only (debug) | ||||
|  | ||||
|  | ||||
|  | ||||
| // FPGA register parameters | ||||
| #define PAGE_SIZE 0x10000                     // default page size for the multicorrelator memory map | ||||
| #define MAX_PHASE_STEP_RAD 0.999999999534339  // 1 - pow(2,-31); | ||||
| #define RESET_ACQUISITION 2                   // command to reset the multicorrelator | ||||
| @@ -59,50 +58,28 @@ | ||||
| #define SELECT_MSB 0XFF00                     // value to select the most significant byte | ||||
| #define SELECT_16_BITS 0xFFFF                 // value to select 16 bits | ||||
| #define SHL_8_BITS 256                        // value used to shift a value 8 bits to the left | ||||
|  | ||||
| // 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 0x000003FF | ||||
| #define SELECT_MSBbits 0x000FFC00 | ||||
| #define SELECT_ALL_CODE_BITS 0x000FFFFF | ||||
| #define SHL_CODE_BITS 1024 | ||||
| #define SELECT_LSBits 0x000003FF		// Select the 10 LSbits out of a 20-bit word | ||||
| #define SELECT_MSBbits 0x000FFC00		// Select the 10 MSbits out of a 20-bit word | ||||
| #define SELECT_ALL_CODE_BITS 0x000FFFFF		// Select a 20 bit word | ||||
| #define SHL_CODE_BITS 1024			// shift left by 10 bits | ||||
|  | ||||
|  | ||||
| bool fpga_acquisition::init() | ||||
| { | ||||
| 	//printf("acq lib init called\n"); | ||||
|     // configure the acquisition with the main initialization values | ||||
|     //fpga_acquisition::configure_acquisition(); | ||||
|     return true; | ||||
| } | ||||
|  | ||||
|  | ||||
| bool fpga_acquisition::set_local_code(uint32_t PRN) | ||||
| { | ||||
| 	//printf("acq lib set_local_code_called\n"); | ||||
|     // select the code with the chosen PRN | ||||
| 	d_PRN = PRN; | ||||
| //	printf("#### ACQ: WRITING LOCAL CODE for PRN %d\n", (int) 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; | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_acquisition::write_local_code() | ||||
| { | ||||
| 	//printf("#### ACQ: WRITING LOCAL CODE for PRN %d\n", (int) d_PRN); | ||||
|  | ||||
|  | ||||
|     fpga_acquisition::fpga_configure_acquisition_local_code( | ||||
|         &d_all_fft_codes[d_nsamples_total * (d_PRN - 1)]); | ||||
|  | ||||
| @@ -116,15 +93,10 @@ fpga_acquisition::fpga_acquisition(std::string device_name, | ||||
|     lv_16sc_t *all_fft_codes, | ||||
| 	uint32_t excludelimit) | ||||
| { | ||||
| 	//printf("acq lib constructor called\n"); | ||||
|     //printf("AAA- sampled_ms = %d\n ", sampled_ms); | ||||
|     uint32_t vector_length = nsamples_total; | ||||
|  | ||||
|     uint32_t vector_length = nsamples_total;  // * sampled_ms; | ||||
|  | ||||
|     //printf("AAA- vector_length = %d\n ", vector_length); | ||||
|     // initial values | ||||
|     d_device_name = std::move(device_name); | ||||
|     //d_freq = freq; | ||||
|     d_fs_in = fs_in; | ||||
|     d_vector_length = vector_length; | ||||
|     d_excludelimit = excludelimit; | ||||
| @@ -136,56 +108,12 @@ fpga_acquisition::fpga_acquisition(std::string device_name, | ||||
|     d_fd = 0;              // driver descriptor | ||||
|     d_map_base = nullptr;  // driver memory map | ||||
|     d_all_fft_codes = all_fft_codes; | ||||
| /* | ||||
|     //printf("acq internal device name = %s\n", d_device_name.c_str()); | ||||
|     // open communication with HW accelerator | ||||
|     if ((d_fd = open(d_device_name.c_str(), O_RDWR | O_SYNC)) == -1) | ||||
|         { | ||||
|             LOG(WARNING) << "Cannot open deviceio" << d_device_name; | ||||
|             std::cout << "Acq: cannot open deviceio" << d_device_name << std::endl; | ||||
|         } | ||||
|     else | ||||
|     { | ||||
|     	//printf("acq lib DEVICE OPENED CORRECTLY\n"); | ||||
|     } | ||||
|     d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(NULL, PAGE_SIZE, | ||||
|         PROT_READ | PROT_WRITE, MAP_SHARED, d_fd, 0)); | ||||
|  | ||||
|     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; | ||||
|         } | ||||
|     else | ||||
|     { | ||||
|     	//printf("acq lib MAP BASE MAPPED CORRECTLY\n"); | ||||
|     } | ||||
|  | ||||
|     // sanity check : check test register | ||||
|     uint32_t writeval = TEST_REG_SANITY_CHECK; | ||||
|     uint32_t readval; | ||||
|     readval = fpga_acquisition::fpga_acquisition_test_register(writeval); | ||||
|     if (writeval != readval) | ||||
|         { | ||||
|             LOG(WARNING) << "Acquisition test register sanity check failed"; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             LOG(INFO) << "Acquisition test register sanity check success!"; | ||||
|             //printf("acq lib REG SANITY CHECK SUCCESS\n"); | ||||
|             //std::cout << "Acquisition test register sanity check success!" << std::endl; | ||||
|         } | ||||
|         */ | ||||
|  | ||||
|     fpga_acquisition::reset_acquisition(); | ||||
|  | ||||
|     fpga_acquisition::open_device(); | ||||
|     fpga_acquisition::fpga_acquisition_test_register(); | ||||
|     fpga_acquisition::close_device(); | ||||
|  | ||||
|     // flag used for testing purposes | ||||
|     d_single_doppler_flag = 0; | ||||
|  | ||||
|     d_PRN = 0; | ||||
|     DLOG(INFO) << "Acquisition FPGA class created"; | ||||
|  | ||||
| @@ -193,17 +121,12 @@ fpga_acquisition::fpga_acquisition(std::string device_name, | ||||
|  | ||||
| void fpga_acquisition::open_device() | ||||
| { | ||||
|     //printf("acq internal device name = %s\n", d_device_name.c_str()); | ||||
|     // open communication with HW accelerator | ||||
|     if ((d_fd = open(d_device_name.c_str(), O_RDWR | O_SYNC)) == -1) | ||||
|         { | ||||
|             LOG(WARNING) << "Cannot open deviceio" << d_device_name; | ||||
|             std::cout << "Acq: cannot open deviceio" << d_device_name << std::endl; | ||||
|         } | ||||
|     else | ||||
|     { | ||||
|     	//printf("acq lib DEVICE OPENED CORRECTLY\n"); | ||||
|     } | ||||
|     d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(NULL, PAGE_SIZE, | ||||
|         PROT_READ | PROT_WRITE, MAP_SHARED, d_fd, 0)); | ||||
|  | ||||
| @@ -212,41 +135,17 @@ void fpga_acquisition::open_device() | ||||
|             LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory"; | ||||
|             std::cout << "Acq: cannot map deviceio" << d_device_name << std::endl; | ||||
|         } | ||||
|     else | ||||
|     { | ||||
|     	//printf("acq lib MAP BASE MAPPED CORRECTLY\n"); | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|     // sanity check : check test register | ||||
|     uint32_t writeval = TEST_REG_SANITY_CHECK; | ||||
|     uint32_t readval; | ||||
|     readval = fpga_acquisition::fpga_acquisition_test_register(writeval); | ||||
|     if (writeval != readval) | ||||
|         { | ||||
|             LOG(WARNING) << "Acquisition test register sanity check failed"; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             LOG(INFO) << "Acquisition test register sanity check success!"; | ||||
|             //printf("acq lib REG SANITY CHECK SUCCESS\n"); | ||||
|             //std::cout << "Acquisition test register sanity check success!" << std::endl; | ||||
|         } | ||||
|  | ||||
|         */ | ||||
|  | ||||
| } | ||||
|  | ||||
| fpga_acquisition::~fpga_acquisition() | ||||
| { | ||||
| 	//printf("acq lib destructor called\n"); | ||||
| 	//fpga_acquisition::close_device(); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| bool fpga_acquisition::free() | ||||
| { | ||||
| 	//printf("acq lib free called\n"); | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| @@ -258,15 +157,12 @@ void fpga_acquisition::fpga_acquisition_test_register() | ||||
|     uint32_t writeval = TEST_REG_SANITY_CHECK; | ||||
|     uint32_t readval; | ||||
|  | ||||
| 	//printf("acq lib test register called\n"); | ||||
|     //uint32_t readval; | ||||
|     // write value to test register | ||||
|     d_map_base[15] = writeval; | ||||
|     // read value from test register | ||||
|     readval = d_map_base[15]; | ||||
|  | ||||
|  | ||||
|     //readval = fpga_acquisition::fpga_acquisition_test_register(writeval); | ||||
|     if (writeval != readval) | ||||
|         { | ||||
|             LOG(WARNING) << "Acquisition test register sanity check failed"; | ||||
| @@ -274,20 +170,7 @@ void fpga_acquisition::fpga_acquisition_test_register() | ||||
|     else | ||||
|         { | ||||
|             LOG(INFO) << "Acquisition test register sanity check success!"; | ||||
|             //printf("acq lib REG SANITY CHECK SUCCESS\n"); | ||||
|             //std::cout << "Acquisition test register sanity check success!" << std::endl; | ||||
|         } | ||||
|  | ||||
| /* | ||||
| 	//printf("acq lib test register called\n"); | ||||
|     uint32_t readval; | ||||
|     // write value to test register | ||||
|     d_map_base[15] = writeval; | ||||
|     // read value from test register | ||||
|     readval = d_map_base[15]; | ||||
|     // return read value | ||||
|     return readval; | ||||
|     */ | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -296,305 +179,109 @@ void fpga_acquisition::fpga_configure_acquisition_local_code(lv_16sc_t fft_local | ||||
|     uint32_t local_code; | ||||
|     uint32_t k, tmp, tmp2; | ||||
|     uint32_t fft_data; | ||||
|     //printf("acq lib fpga_configure_acquisition_local_code_called\n"); | ||||
|     // clear memory address counter | ||||
|     //d_map_base[6] = LOCAL_CODE_CLEAR_MEM; | ||||
|  | ||||
| 	//printf("writing local code for d_PRN = %d\n", (int) d_PRN); | ||||
| 	//printf("writing local code d_nsamples_total = %d\n", (int) d_nsamples_total); | ||||
| 	//printf("writing local code d_vector_length = %d\n", (int) d_vector_length); | ||||
|     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(); | ||||
|             //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_CODE_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_ALL_CODE_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("acq d_vector_length = %d\n", d_vector_length); | ||||
|     //while(1); | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_acquisition::run_acquisition(void) | ||||
| { | ||||
|  | ||||
|  | ||||
| 	//uint32_t result_valid = 0; | ||||
|     //while(result_valid == 0) | ||||
|     //{ | ||||
|     //	read_result_valid(&result_valid); // polling | ||||
|     //} | ||||
| 	//printf("acq lib run_acqisition called\n"); | ||||
|     // enable interrupts | ||||
|     int32_t reenable = 1; | ||||
|     int32_t disable_int = 0; | ||||
|     //reenable = 1; | ||||
|     write(d_fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t)); | ||||
|  | ||||
|     // launch the acquisition process | ||||
|     //printf("acq lib launchin acquisition ...\n"); | ||||
| 	//printf("acq lib launch acquisition\n"); | ||||
|     d_map_base[8] = LAUNCH_ACQUISITION;  // writing a 1 to reg 8 launches the acquisition process | ||||
|     //printf("acq lib waiting for interrupt ...\n"); | ||||
|     int32_t irq_count; | ||||
|     ssize_t nb; | ||||
|  | ||||
|     //uint32_t result_valid = 0; | ||||
|  | ||||
|     //usleep(5000000); | ||||
|     //printf("acq lib waiting for result valid\n"); | ||||
|     //while(result_valid == 0) | ||||
|     //{ | ||||
|     //	read_result_valid(&result_valid); // polling | ||||
|     //} | ||||
|     //printf("result valid\n"); | ||||
|     // wait for interrupt | ||||
|     nb = read(d_fd, &irq_count, sizeof(irq_count)); | ||||
|     //usleep(500000); // debug | ||||
|     //printf("interrupt received\n"); | ||||
|     if (nb != sizeof(irq_count)) | ||||
|         { | ||||
|             printf("acquisition module Read failed to retrieve 4 bytes!\n"); | ||||
|             printf("acquisition module Interrupt number %d\n", irq_count); | ||||
|         } | ||||
|  | ||||
|  | ||||
|     write(d_fd, reinterpret_cast<void *>(&disable_int), sizeof(int32_t)); | ||||
|  | ||||
| } | ||||
|  | ||||
| void fpga_acquisition::set_block_exp(uint32_t total_block_exp) | ||||
| { | ||||
| 	//printf("******* acq writing total exponent = %d\n", (int) total_block_exp); | ||||
| 	d_map_base[11] = total_block_exp; | ||||
| } | ||||
|  | ||||
| void fpga_acquisition::set_doppler_sweep(uint32_t num_sweeps) | ||||
| { | ||||
| 	//printf("writing doppler_max = %d\n", (int) d_doppler_max); | ||||
| 	//printf("writing doppler_step = %d\n", (int) d_doppler_step); | ||||
| 	//printf("num_sweeps = %d\n", num_sweeps); | ||||
|  | ||||
| 	if (d_single_doppler_flag == 0) | ||||
| 	{ | ||||
| 		//printf("acq lib set_doppler_sweep called\n"); | ||||
| 	    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) | ||||
| 	// 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) | ||||
| 	phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); | ||||
|  | ||||
| 	    //printf("AAA  phase_step_rad_real for initial doppler = %f\n", phase_step_rad_real); | ||||
| 	// avoid saturation of the fixed point representation in the fpga | ||||
| 	// (only the positive value can saturate due to the 2's complement representation) | ||||
| 	    if (phase_step_rad_real >= 1.0) | ||||
| 	        { | ||||
| 	            phase_step_rad_real = MAX_PHASE_STEP_RAD; | ||||
| 	        } | ||||
| 	    //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_incr 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; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		//printf("acq lib set_doppler_sweep called\n"); | ||||
| 	    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; | ||||
| 	    //printf("executing with doppler = %d\n", (int) d_doppler_max); | ||||
| 	    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; | ||||
|  | ||||
| 	    //printf("executing with doppler step = %d\n", (int) d_doppler_step); | ||||
| 	    // 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 = 1\n"); | ||||
| 	    d_map_base[5] = 1;  // 1 sweep | ||||
|  | ||||
| 	} | ||||
|  | ||||
|  | ||||
| } | ||||
| /* | ||||
| void fpga_acquisition::set_doppler_sweep_debug(uint32_t num_sweeps, uint32_t doppler_index) | ||||
| { | ||||
| 	//printf("acq lib set_doppler_sweep_debug called\n"); | ||||
|     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() | ||||
| { | ||||
| 	fpga_acquisition::open_device(); | ||||
|  | ||||
| 	//printf("acq lib configure acquisition called\n"); | ||||
|  | ||||
|     d_map_base[0] = d_select_queue; | ||||
|     //printf("AAA d_select_queue = %d\n", d_select_queue); | ||||
|     //d_map_base[0] = 1; | ||||
|     //printf("acq internal writing d_vector_length = %d to d map base 1\n ", d_vector_length); | ||||
|     d_map_base[1] = d_vector_length; | ||||
|     //printf("acq interal writing d_nsamples = %d to d map base 2\n ", d_nsamples); | ||||
|     d_map_base[2] = d_nsamples; | ||||
|     //printf("AAA writing LOG2 d_vector_length = %d to d map base 7\n ", (int)log2((float)d_vector_length)); | ||||
|     d_map_base[7] = static_cast<int32_t>(log2(static_cast<float>(d_vector_length)));  // log2 FFTlength | ||||
|     //printf("AAA writing excludelimit = %d to d map base 12\n", (int) d_excludelimit); | ||||
|     d_map_base[12] = d_excludelimit; | ||||
|  | ||||
|     //printf("acquisition debug vector length = %d\n", d_vector_length); | ||||
|     //printf("acquisition debug vector length = %d\n", (int)log2((float)d_vector_length)); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //void fpga_acquisition::configure_acquisition_debug() | ||||
| //{ | ||||
| //	fpga_acquisition::open_device(); | ||||
| // | ||||
| //	//printf("acq lib configure acquisition called\n"); | ||||
| // //   d_map_base[0] = d_select_queue; | ||||
| //    //printf("AAA d_select_queue = %d\n", d_select_queue); | ||||
| // | ||||
| //    //usleep(500000); | ||||
| //    //d_map_base[0] = 1; | ||||
| //    //printf("acq internal writing d_vector_length = %d to d map base 1\n ", d_vector_length); | ||||
| ///*    d_map_base[1] = d_vector_length; | ||||
| //    //printf("acq interal writing d_nsamples = %d to d map base 2\n ", d_nsamples); | ||||
| //    d_map_base[2] = d_nsamples; | ||||
| //    //printf("AAA writing LOG2 d_vector_length = %d to d map base 7\n ", (int)log2((float)d_vector_length)); | ||||
| //    d_map_base[7] = static_cast<int32_t>(log2(static_cast<float>(d_vector_length)));  // log2 FFTlength | ||||
| //    //printf("AAA writing excludelimit = %d to d map base 12\n", (int) d_excludelimit); | ||||
| //    d_map_base[12] = d_excludelimit; | ||||
| //*/ | ||||
| //    //printf("acquisition debug vector length = %d\n", d_vector_length); | ||||
| //    //printf("acquisition debug vector length = %d\n", (int)log2((float)d_vector_length)); | ||||
| //} | ||||
|  | ||||
|  | ||||
|  | ||||
| void fpga_acquisition::set_phase_step(uint32_t doppler_index) | ||||
| { | ||||
| 	//printf("acq lib set phase step SHOULD NOT BE called\n"); | ||||
|     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; | ||||
|     //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) | ||||
| @@ -603,15 +290,12 @@ 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 = 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 THE SECOND FUNCTION\n", phase_step_rad_int); | ||||
|     d_map_base[3] = phase_step_rad_int; | ||||
| } | ||||
|  | ||||
| @@ -620,22 +304,11 @@ void fpga_acquisition::read_acquisition_results(uint32_t *max_index, | ||||
|     float *firstpeak, float *secondpeak, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index, uint32_t *total_blk_exp) | ||||
| { | ||||
|  | ||||
| 	//do | ||||
| 	//{ | ||||
|  | ||||
|  | ||||
| 	//usleep(500000); | ||||
| 	//printf("reading results\n"); | ||||
|  | ||||
| 	//printf("acq lib read_acquisition_results_called\n"); | ||||
|     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_tmp = readval; | ||||
|  | ||||
| @@ -644,42 +317,26 @@ void fpga_acquisition::read_acquisition_results(uint32_t *max_index, | ||||
|  | ||||
|     initial_sample_tmp = initial_sample_tmp + readval_long_shifted;  // 2^32 | ||||
|     *initial_sample = initial_sample_tmp; | ||||
|     //printf("-------> acq initial sample TOTAL = %llu\n", *initial_sample); | ||||
|  | ||||
|     readval = d_map_base[3]; | ||||
|     *firstpeak = static_cast<float>(readval); | ||||
|     //printf("-------> read first peak = %f\n", *firstpeak); | ||||
|  | ||||
|     readval = d_map_base[4]; | ||||
|     *secondpeak = static_cast<float>(readval); | ||||
|     //printf("-------> read second peak = %f\n", *secondpeak); | ||||
|  | ||||
|     readval = d_map_base[5]; | ||||
|     *max_index = readval; | ||||
|     //printf("-------> read max index = %d\n", (int) *max_index); | ||||
|  | ||||
|     //printf("acq lib read max_magnitude dmap 2 = %d = %f\n", readval, *max_magnitude); | ||||
|     //readval = d_map_base[4]; | ||||
|     *power_sum = 0; | ||||
|     //printf("acq lib read power sum dmap 4 = %d = %f\n", readval, *power_sum); | ||||
|  | ||||
|  | ||||
|  | ||||
|     readval = d_map_base[8]; | ||||
|     *total_blk_exp = readval; | ||||
|     //printf("---------> read total block exponent = %d\n", (int) *total_blk_exp); | ||||
|  | ||||
|     readval = d_map_base[7];  // read doppler index -- this read releases the interrupt line | ||||
|     *doppler_index = readval; | ||||
|     //printf("---------> read doppler_index = %d\n", (int) *doppler_index ); | ||||
|  | ||||
|     readval = d_map_base[15]; // read dummy | ||||
|  | ||||
| 	//} while (*total_blk_exp == 11); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     fpga_acquisition::close_device(); | ||||
|  | ||||
| } | ||||
| @@ -687,21 +344,18 @@ void fpga_acquisition::read_acquisition_results(uint32_t *max_index, | ||||
|  | ||||
| void fpga_acquisition::block_samples() | ||||
| { | ||||
| 	//printf("acq lib block samples called\n"); | ||||
|     d_map_base[14] = 1;  // block the samples | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_acquisition::unblock_samples() | ||||
| { | ||||
| 	//printf("acq lib unblock samples called\n"); | ||||
|     d_map_base[14] = 0;  // unblock the samples | ||||
| } | ||||
|  | ||||
|  | ||||
| void fpga_acquisition::close_device() | ||||
| { | ||||
| 	//printf("acq lib close device called\n"); | ||||
|     uint32_t *aux = const_cast<uint32_t *>(d_map_base); | ||||
|     if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1) | ||||
|         { | ||||
| @@ -714,16 +368,10 @@ void fpga_acquisition::close_device() | ||||
| void fpga_acquisition::reset_acquisition(void) | ||||
| { | ||||
| 	fpga_acquisition::open_device(); | ||||
| 	//printf("acq lib reset acquisition called\n"); | ||||
|     d_map_base[8] = RESET_ACQUISITION;  // writing a 2 to d_map_base[8] resets the multicorrelator | ||||
|     fpga_acquisition::close_device(); | ||||
| } | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void fpga_acquisition::set_single_doppler_flag(unsigned int single_doppler_flag) | ||||
| { | ||||
| 	d_single_doppler_flag = single_doppler_flag; | ||||
| } | ||||
|  | ||||
| // this function is only used for the unit tests | ||||
| void fpga_acquisition::read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor) | ||||
| @@ -736,7 +384,6 @@ void fpga_acquisition::read_fpga_total_scale_factor(uint32_t *total_scale_factor | ||||
| 	//readval = d_map_base[8]; | ||||
| 	*fw_scale_factor = 0; | ||||
|  | ||||
| 	//printf("reading scale factor of %d\n", (int) readval); | ||||
| } | ||||
|  | ||||
| void fpga_acquisition::read_result_valid(uint32_t *result_valid) | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * \file fpga_acquisition.h | ||||
|  * \brief High optimized FPGA vector correlator class | ||||
|  * \authors <ul> | ||||
|  *          <li> Marc Majoral, 2018. mmajoral(at)cttc.cat | ||||
|  *          <li> Marc Majoral, 2019. mmajoral(at)cttc.cat | ||||
|  *          </ul> | ||||
|  * | ||||
|  * Class that controls and executes a high optimized acquisition HW | ||||
| @@ -10,7 +10,7 @@ | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||
|  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
| @@ -61,14 +61,10 @@ public: | ||||
|     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, | ||||
|     //    uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index); | ||||
|     void read_acquisition_results(uint32_t *max_index, float *firstpeak, float *secondpeak, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index, uint32_t *total_blk_exp); | ||||
|  | ||||
|  | ||||
|     void block_samples(); | ||||
|     void unblock_samples(); | ||||
|  | ||||
| @@ -78,9 +74,7 @@ public: | ||||
|      */ | ||||
|     void set_doppler_max(uint32_t doppler_max) | ||||
|     { | ||||
|     	//printf("acq lib set doppler max called\n"); | ||||
|         d_doppler_max = doppler_max; | ||||
|         //printf("set acq lib d_doppler_max = %d\n", (int) d_doppler_max); | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
| @@ -89,23 +83,16 @@ public: | ||||
|      */ | ||||
|     void set_doppler_step(uint32_t doppler_step) | ||||
|     { | ||||
|     	//printf("acq lib set doppler step called\n"); | ||||
|         d_doppler_step = doppler_step; | ||||
|         //printf("set acq lib d_doppler_step = %d\n", (int) d_doppler_step); | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
|      * \brief this function is only used in the unit test | ||||
|      */ | ||||
|     void set_single_doppler_flag(unsigned int single_doppler_flag); | ||||
|  | ||||
|     /*! | ||||
|      * \brief this function is only used in the unit test | ||||
|      * \brief Reset the FPGA PL. | ||||
|      */ | ||||
|     void reset_acquisition(void); | ||||
|  | ||||
|     /*! | ||||
|      * \brief this function is only used in the unit test | ||||
|      * \brief read the scaling factor that has been used by the FFT-IFFT | ||||
|      */ | ||||
|     void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); | ||||
|  | ||||
| @@ -137,13 +124,8 @@ private: | ||||
|     // FPGA private functions | ||||
|     void fpga_acquisition_test_register(void); | ||||
|     void fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]); | ||||
|     //void configure_acquisition(); | ||||
| //    void close_device(); | ||||
| //    void open_device(); | ||||
|     void read_result_valid(uint32_t *result_valid); | ||||
|  | ||||
|     // test parameters | ||||
|     unsigned int d_single_doppler_flag; // this flag is only used for testing purposes | ||||
| }; | ||||
|  | ||||
| #endif /* GNSS_SDR_FPGA_ACQUISITION_H_ */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Marc Majoral
					Marc Majoral