mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-29 22:42:59 +00:00 
			
		
		
		
	Replacing software sample counter with hardware sample counter if FPGA is enabled. Fix a compilation bug when ENABLE_FPGA is selected
This commit is contained in:
		| @@ -60,7 +60,7 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( | ||||
|     long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); | ||||
|     long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||
|     acq_parameters.fs_in = fs_in; | ||||
|     acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.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_; | ||||
|   | ||||
| @@ -40,6 +40,7 @@ if(ENABLE_FPGA) | ||||
|         conjugate_cc.cc | ||||
|         conjugate_sc.cc | ||||
|         conjugate_ic.cc | ||||
|         gnss_sdr_fpga_sample_counter.cc | ||||
| 	) | ||||
| else(ENABLE_FPGA) | ||||
|     set(GNSS_SPLIBS_SOURCES | ||||
|   | ||||
							
								
								
									
										171
									
								
								src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,171 @@ | ||||
| /*! | ||||
|  * \file gnss_sdr_fpga_sample_counter.cc | ||||
|  * \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks | ||||
|  * \author Javier Arribas 2018. jarribas(at)cttc.es | ||||
|  * | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "gnss_sdr_fpga_sample_counter.h" | ||||
| #include "gnss_synchro.h" | ||||
| #include <gnuradio/io_signature.h> | ||||
| #include <cmath> | ||||
| #include <iostream> | ||||
| #include <string> | ||||
|  | ||||
| gnss_sdr_fpga_sample_counter::gnss_sdr_fpga_sample_counter(double _fs, int _interval_ms) : gr::block("fpga_fpga_sample_counter", | ||||
|                                                                                                gr::io_signature::make(0, 0, 0), | ||||
|                                                                                                gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) | ||||
| { | ||||
|     message_port_register_out(pmt::mp("fpga_sample_counter")); | ||||
|     set_max_noutput_items(1); | ||||
|     interval_ms = _interval_ms; | ||||
|     fs = _fs; | ||||
|     samples_per_output = std::round(fs * static_cast<double>(interval_ms) / 1e3); | ||||
|     //todo: Load here the hardware counter register with this amount of samples. It should produde an | ||||
|     //interrupt every samples_per_output count. | ||||
|     //The hardware timmer must keep always interrupting the PS. It must not wait for the interrupt to | ||||
|     //be served. | ||||
|  | ||||
|     sample_counter = 0; | ||||
|     current_T_rx_ms = 0; | ||||
|     current_s = 0; | ||||
|     current_m = 0; | ||||
|     current_h = 0; | ||||
|     current_days = 0; | ||||
|     report_interval_ms = 1000;     // default reporting 1 second | ||||
|     flag_enable_send_msg = false;  // enable it for reporting time with asynchronous message | ||||
|     flag_m = false; | ||||
|     flag_h = false; | ||||
|     flag_days = false; | ||||
| } | ||||
|  | ||||
|  | ||||
| gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int _interval_ms) | ||||
| { | ||||
|     gnss_sdr_fpga_sample_counter_sptr fpga_sample_counter_(new gnss_sdr_fpga_sample_counter(_fs, _interval_ms)); | ||||
|     return fpga_sample_counter_; | ||||
| } | ||||
|  | ||||
|  | ||||
| // Called by gnuradio to enable drivers, etc for i/o devices. | ||||
| bool gnss_sdr_fpga_sample_counter::start() | ||||
| { | ||||
|     //todo: place here the RE-INITIALIZATION routines. This function will be called by GNURadio at every start of the flowgraph. | ||||
|     // return true if everything is ok. | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| // Called by GNURadio to disable drivers, etc for i/o devices. | ||||
| bool gnss_sdr_fpga_sample_counter::stop() | ||||
| { | ||||
|     //todo: place here the routines to stop the associated hardware (if needed).This function will be called by GNURadio at every stop of the flowgraph. | ||||
|     // return true if everything is ok. | ||||
|     return true; | ||||
| } | ||||
|  | ||||
|  | ||||
| int gnss_sdr_fpga_sample_counter::general_work(int noutput_items __attribute__((unused)), | ||||
|     __attribute__((unused)) gr_vector_int &ninput_items, | ||||
|     __attribute__((unused)) gr_vector_const_void_star &input_items, | ||||
|     gr_vector_void_star &output_items) | ||||
| { | ||||
|     //todo: Call here a function that waits for an interrupt. Do not open a thread, | ||||
|     //it must be a simple call to a BLOCKING function. | ||||
|     // The function will return the actual absolute sample count of the internal counter of the timmer. | ||||
|     // store the sample count in class member sample_counter | ||||
|     // Possible problem: what happen if the PS is overloaded and gnuradio does not call this function | ||||
|     // with the sufficient rate to catch all the interrupts in the counter. To be evaluated later. | ||||
|  | ||||
|  | ||||
|     Gnss_Synchro *out = reinterpret_cast<Gnss_Synchro *>(output_items[0]); | ||||
|     out[0] = Gnss_Synchro(); | ||||
|     out[0].Flag_valid_symbol_output = false; | ||||
|     out[0].Flag_valid_word = false; | ||||
|     out[0].Channel_ID = -1; | ||||
|     out[0].fs = fs; | ||||
|     if ((current_T_rx_ms % report_interval_ms) == 0) | ||||
|         { | ||||
|             current_s++; | ||||
|             if ((current_s % 60) == 0) | ||||
|                 { | ||||
|                     current_s = 0; | ||||
|                     current_m++; | ||||
|                     flag_m = true; | ||||
|                     if ((current_m % 60) == 0) | ||||
|                         { | ||||
|                             current_m = 0; | ||||
|                             current_h++; | ||||
|                             flag_h = true; | ||||
|                             if ((current_h % 24) == 0) | ||||
|                                 { | ||||
|                                     current_h = 0; | ||||
|                                     current_days++; | ||||
|                                     flag_days = true; | ||||
|                                 } | ||||
|                         } | ||||
|                 } | ||||
|  | ||||
|             if (flag_days) | ||||
|                 { | ||||
|                     std::string day; | ||||
|                     if (current_days == 1) | ||||
|                         { | ||||
|                             day = " day "; | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             day = " days "; | ||||
|                         } | ||||
|                     std::cout << "Current receiver time: " << current_days << day << current_h << " h " << current_m << " min " << current_s << " s" << std::endl; | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     if (flag_h) | ||||
|                         { | ||||
|                             std::cout << "Current receiver time: " << current_h << " h " << current_m << " min " << current_s << " s" << std::endl; | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             if (flag_m) | ||||
|                                 { | ||||
|                                     std::cout << "Current receiver time: " << current_m << " min " << current_s << " s" << std::endl; | ||||
|                                 } | ||||
|                             else | ||||
|                                 { | ||||
|                                     std::cout << "Current receiver time: " << current_s << " s" << std::endl; | ||||
|                                 } | ||||
|                         } | ||||
|                 } | ||||
|             if (flag_enable_send_msg) | ||||
|                 { | ||||
|                     message_port_pub(pmt::mp("receiver_time"), pmt::from_double(static_cast<double>(current_T_rx_ms) / 1000.0)); | ||||
|                 } | ||||
|         } | ||||
|     out[0].Tracking_sample_counter = sample_counter; | ||||
|     current_T_rx_ms = (sample_counter * 1000) / samples_per_output; | ||||
|     return 1; | ||||
| } | ||||
							
								
								
									
										73
									
								
								src/algorithms/libs/gnss_sdr_fpga_sample_counter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/algorithms/libs/gnss_sdr_fpga_sample_counter.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| /*! | ||||
|  * \file gnss_sdr_fpga_sample_counter.h | ||||
|  * \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks | ||||
|  * \author Javier Arribas 2018. jarribas(at)cttc.es | ||||
|  * | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||
|  * | ||||
|  * GNSS-SDR is a software defined Global Navigation | ||||
|  *          Satellite Systems receiver | ||||
|  * | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GNSS-SDR is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
| #ifndef GNSS_SDR_FPGA_sample_counter_H_ | ||||
| #define GNSS_SDR_FPGA_sample_counter_H_ | ||||
|  | ||||
| #include <gnuradio/block.h> | ||||
| #include <boost/shared_ptr.hpp> | ||||
|  | ||||
|  | ||||
| class gnss_sdr_fpga_sample_counter; | ||||
|  | ||||
| typedef boost::shared_ptr<gnss_sdr_fpga_sample_counter> gnss_sdr_fpga_sample_counter_sptr; | ||||
|  | ||||
| gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int _interval_ms); | ||||
|  | ||||
| class gnss_sdr_fpga_sample_counter : public gr::block | ||||
| { | ||||
| private: | ||||
|     gnss_sdr_fpga_sample_counter(double _fs, int _interval_ms); | ||||
|     bool start(); | ||||
|     bool stop(); | ||||
|     unsigned int samples_per_output; | ||||
|     double fs; | ||||
|     unsigned long long int sample_counter; | ||||
|     int interval_ms; | ||||
|     long long int current_T_rx_ms;  // Receiver time in ms since the beginning of the run | ||||
|     unsigned int current_s;         // Receiver time in seconds, modulo 60 | ||||
|     bool flag_m;                    // True if the receiver has been running for at least 1 minute | ||||
|     unsigned int current_m;         // Receiver time in minutes, modulo 60 | ||||
|     bool flag_h;                    // True if the receiver has been running for at least 1 hour | ||||
|     unsigned int current_h;         // Receiver time in hours, modulo 24 | ||||
|     bool flag_days;                 // True if the receiver has been running for at least 1 day | ||||
|     unsigned int current_days;      // Receiver time in days since the beginning of the run | ||||
|     int report_interval_ms; | ||||
|     bool flag_enable_send_msg; | ||||
|  | ||||
| public: | ||||
|     friend gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int _interval_ms); | ||||
|     int general_work(int noutput_items, | ||||
|         gr_vector_int &ninput_items, | ||||
|         gr_vector_const_void_star &input_items, | ||||
|         gr_vector_void_star &output_items); | ||||
| }; | ||||
|  | ||||
| #endif /*GNSS_SDR_FPGA_sample_counter_H_*/ | ||||
| @@ -292,22 +292,23 @@ void GNSSFlowgraph::connect() | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             //create a software-defined 1kHz gnss_synchro pulse for the observables block | ||||
|             //create a hardware-defined gnss_synchro pulse for the observables block | ||||
|             try | ||||
|                 { | ||||
|                     //null source | ||||
|                     null_source_ = gr::blocks::null_source::make(sizeof(Gnss_Synchro)); | ||||
|                     //throttle to observable interval | ||||
|                     double fs = static_cast<double>(configuration_->property("GNSS-SDR.internal_fs_sps", 0)); | ||||
|                     if (fs == 0.0) | ||||
|                         { | ||||
|                             LOG(WARNING) << "Set GNSS-SDR.internal_fs_sps in configuration file"; | ||||
|                             std::cout << "Set GNSS-SDR.internal_fs_sps in configuration file" << std::endl; | ||||
|                             throw(std::invalid_argument("Set GNSS-SDR.internal_fs_sps in configuration")); | ||||
|                         } | ||||
|                     int observable_interval_ms = static_cast<double>(configuration_->property("GNSS-SDR.observable_interval_ms", 20)); | ||||
|                     throttle_ = gr::blocks::throttle::make(sizeof(Gnss_Synchro), std::round(1.0 / static_cast<double>(observable_interval_ms)));  // 1000 samples per second (1kHz) | ||||
|                     time_counter_ = gnss_sdr_make_time_counter(); | ||||
|                     top_block_->connect(null_source_, 0, throttle_, 0); | ||||
|                     top_block_->connect(throttle_, 0, time_counter_, 0); | ||||
|                     top_block_->connect(time_counter_, 0, observables_->get_left_block(), channels_count_); | ||||
|                     ch_out_fpga_sample_counter = gnss_sdr_make_fpga_sample_counter(fs, observable_interval_ms); | ||||
|                     top_block_->connect(ch_out_fpga_sample_counter, 0, observables_->get_left_block(), channels_count_);  //extra port for the sample counter pulse | ||||
|                 } | ||||
|             catch (const std::exception& e) | ||||
|                 { | ||||
|                     LOG(WARNING) << "Can't connect sample counter"; | ||||
|                     LOG(WARNING) << "Can't connect FPGA sample counter"; | ||||
|                     LOG(ERROR) << e.what(); | ||||
|                     top_block_->disconnect_all(); | ||||
|                     return; | ||||
| @@ -633,13 +634,11 @@ void GNSSFlowgraph::disconnect() | ||||
|         { | ||||
|             try | ||||
|                 { | ||||
|                     top_block_->disconnect(null_source_, 0, throttle_, 0); | ||||
|                     top_block_->disconnect(throttle_, 0, time_counter_, 0); | ||||
|                     top_block_->disconnect(time_counter_, 0, observables_->get_left_block(), channels_count_); | ||||
|                     top_block_->disconnect(ch_out_fpga_sample_counter, 0, observables_->get_left_block(), channels_count_); | ||||
|                 } | ||||
|             catch (const std::exception& e) | ||||
|                 { | ||||
|                     LOG(WARNING) << "Can't connect sample counter"; | ||||
|                     LOG(WARNING) << "Can't connect FPGA sample counter"; | ||||
|                     LOG(ERROR) << e.what(); | ||||
|                     top_block_->disconnect_all(); | ||||
|                     return; | ||||
|   | ||||
| @@ -43,8 +43,6 @@ | ||||
| #include "gnss_synchro_monitor.h" | ||||
| #include <gnuradio/top_block.h> | ||||
| #include <gnuradio/msg_queue.h> | ||||
| #include <gnuradio/blocks/null_source.h> | ||||
| #include <gnuradio/blocks/throttle.h> | ||||
| #include <list> | ||||
| #include <map> | ||||
| #include <memory> | ||||
| @@ -54,7 +52,7 @@ | ||||
| #include <vector> | ||||
|  | ||||
| #if ENABLE_FPGA | ||||
| #include "gnss_sdr_time_counter.h" | ||||
| #include "gnss_sdr_fpga_sample_counter.h" | ||||
| #endif | ||||
|  | ||||
| class GNSSBlockInterface; | ||||
| @@ -157,10 +155,8 @@ private: | ||||
|     std::vector<std::shared_ptr<ChannelInterface>> channels_; | ||||
|     gnss_sdr_sample_counter_sptr ch_out_sample_counter; | ||||
| #if ENABLE_FPGA | ||||
|     gnss_sdr_time_counter_sptr time_counter_; | ||||
|     gnss_sdr_fpga_sample_counter_sptr ch_out_fpga_sample_counter; | ||||
| #endif | ||||
|     gr::blocks::null_source::sptr null_source_; | ||||
|     gr::blocks::throttle::sptr throttle_; | ||||
|     gr::top_block_sptr top_block_; | ||||
|     gr::msg_queue::sptr queue_; | ||||
|  | ||||
|   | ||||
| @@ -211,7 +211,7 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) | ||||
|    find_package(GPSTK) | ||||
|    if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) | ||||
|       message(STATUS "GPSTk v${GNSSSDR_GPSTK_LOCAL_VERSION} will be automatically downloaded and built when doing 'make'.") | ||||
|       if(NOT ENABLE_FPGA) | ||||
|  #     if(NOT ENABLE_FPGA) | ||||
|           if(CMAKE_VERSION VERSION_LESS 3.2) | ||||
|            ExternalProject_Add( | ||||
|              gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} | ||||
| @@ -245,10 +245,10 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) | ||||
|           add_definitions(-DGPSTK_BINDIR="${GPSTK_BINDIR}") | ||||
|           set(gpstk_libs gpstk) | ||||
|           set(OWN_GPSTK True) | ||||
|       else(NOT ENABLE_FPGA) | ||||
|           message(STATUS "GPSTk has not been found, try to install it on target.") | ||||
|           message(STATUS "Some extra tests requiring GPSTk will not be built.") | ||||
|       endif(NOT ENABLE_FPGA) | ||||
| #      else(NOT ENABLE_FPGA) | ||||
| #          message(STATUS "GPSTk has not been found, try to install it on target.") | ||||
| #          message(STATUS "Some extra tests requiring GPSTk will not be built.") | ||||
| #      endif(NOT ENABLE_FPGA) | ||||
|    else(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) | ||||
|        set(gpstk_libs ${GPSTK_LIBRARIES}) | ||||
|        set(GPSTK_INCLUDE_DIRS ${GPSTK_INCLUDE_DIR}) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Javier Arribas
					Javier Arribas