diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc index a8e2a3f17..f9625bae5 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc @@ -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(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast(acq_parameters.fs_in))); + acq_parameters.samples_per_code = static_cast(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast(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_; diff --git a/src/algorithms/libs/CMakeLists.txt b/src/algorithms/libs/CMakeLists.txt index bdce5d1cf..306a755cf 100644 --- a/src/algorithms/libs/CMakeLists.txt +++ b/src/algorithms/libs/CMakeLists.txt @@ -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 diff --git a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc new file mode 100644 index 000000000..661275538 --- /dev/null +++ b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc @@ -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 . + * + * ------------------------------------------------------------------------- + */ + +#include "gnss_sdr_fpga_sample_counter.h" +#include "gnss_synchro.h" +#include +#include +#include +#include + +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(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(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(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; +} diff --git a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h new file mode 100644 index 000000000..684feaffa --- /dev/null +++ b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h @@ -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 . + * + * ------------------------------------------------------------------------- + */ +#ifndef GNSS_SDR_FPGA_sample_counter_H_ +#define GNSS_SDR_FPGA_sample_counter_H_ + +#include +#include + + +class gnss_sdr_fpga_sample_counter; + +typedef boost::shared_ptr 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_*/ diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index d8a1e6332..3793709f7 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -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(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(configuration_->property("GNSS-SDR.observable_interval_ms", 20)); - throttle_ = gr::blocks::throttle::make(sizeof(Gnss_Synchro), std::round(1.0 / static_cast(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; diff --git a/src/core/receiver/gnss_flowgraph.h b/src/core/receiver/gnss_flowgraph.h index 00a6ced4e..49b25eef4 100644 --- a/src/core/receiver/gnss_flowgraph.h +++ b/src/core/receiver/gnss_flowgraph.h @@ -43,8 +43,6 @@ #include "gnss_synchro_monitor.h" #include #include -#include -#include #include #include #include @@ -54,7 +52,7 @@ #include #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> 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_; diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index ac70b816e..2469bc33a 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -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})