From a9c7b4113b2a3cde3d99edf84b5feb035a8aa3d2 Mon Sep 17 00:00:00 2001 From: Marc Majoral Date: Fri, 1 Mar 2019 11:13:34 +0100 Subject: [PATCH] The switch bug is solved. Now the switch uses an absolute sample counter --- .../libs/gnss_sdr_fpga_sample_counter.cc | 57 +++++++------------ .../libs/gnss_sdr_fpga_sample_counter.h | 7 ++- 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc index 51f3a6547..6ac958de0 100644 --- a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc +++ b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc @@ -1,12 +1,13 @@ /*! * \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 Marc Majoral 2019. mmajoral(at)cttc.es * \author Javier Arribas 2018. jarribas(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 @@ -54,19 +55,16 @@ gnss_sdr_fpga_sample_counter::gnss_sdr_fpga_sample_counter( 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 produce an - //interrupt every samples_per_output count. - //The hardware timer must keep always interrupting the PS. It must not wait for the interrupt to - //be served. open_device(); - sample_counter = 0ULL; + last_sample_counter = 0ULL; 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 + report_interval_ms = 1000; // default reporting 1 second + samples_per_report = std::round(fs * static_cast(report_interval_ms) / 1e3); flag_enable_send_msg = false; // enable it for reporting time with asynchronous message flag_m = false; flag_h = false; @@ -84,8 +82,6 @@ gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, // 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. - // configure the number of samples per output in the FPGA and enable the interrupts configure_samples_per_output(samples_per_output); @@ -93,14 +89,12 @@ bool gnss_sdr_fpga_sample_counter::start() 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. close_device(); + // return true if everything is ok. return true; } @@ -110,29 +104,27 @@ int gnss_sdr_fpga_sample_counter::general_work(int noutput_items __attribute__(( __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. + wait_for_interrupt(); - uint32_t counter = wait_for_interrupt_and_read_counter(); - uint64_t samples_passed = 2 * static_cast(samples_per_output) - static_cast(counter); // ellapsed samples - // Note: at this moment the sample counter is implemented as a sample counter that decreases to zero and then it is automatically - // reloaded again and keeps counter. It is done in this way to minimize the logic in the FPGA and maximize the FPGA clock performance - // (it takes less resources and latency in the FPGA to compare a number against a fixed value like zero than to compare it to a programmable - // variable number). + uint64_t sample_counter_tmp, sample_counter_msw_tmp; + sample_counter_tmp = map_base[0]; + sample_counter_msw_tmp = map_base[1]; + sample_counter_msw_tmp = sample_counter_msw_tmp << 32; + sample_counter_tmp = sample_counter_tmp + sample_counter_msw_tmp; // 2^32 + sample_counter = sample_counter_tmp; - sample_counter = sample_counter + samples_passed; //samples_per_output; auto *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) + + + if ((sample_counter - last_sample_counter) > samples_per_report) { + last_sample_counter = sample_counter; + current_s++; if ((current_s % 60) == 0) { @@ -190,7 +182,6 @@ int gnss_sdr_fpga_sample_counter::general_work(int noutput_items __attribute__(( } } out[0].Tracking_sample_counter = sample_counter; - //current_T_rx_ms = (sample_counter * 1000) / samples_per_output; current_T_rx_ms = interval_ms * (sample_counter) / samples_per_output; return 1; } @@ -240,7 +231,6 @@ void gnss_sdr_fpga_sample_counter::open_device() else { LOG(INFO) << "Acquisition test register sanity check success!"; - //std::cout << "Acquisition test register sanity check success!" << std::endl; } } @@ -256,11 +246,11 @@ void gnss_sdr_fpga_sample_counter::close_device() close(fd); } -uint32_t gnss_sdr_fpga_sample_counter::wait_for_interrupt_and_read_counter() +//uint32_t gnss_sdr_fpga_sample_counter::wait_for_interrupt_and_read_counter() +void gnss_sdr_fpga_sample_counter::wait_for_interrupt() { int32_t irq_count; ssize_t nb; - int32_t counter; // enable interrupts int32_t reenable = 1; @@ -273,11 +263,4 @@ uint32_t gnss_sdr_fpga_sample_counter::wait_for_interrupt_and_read_counter() std::cout << "fpga sample counter module read failed to retrieve 4 bytes!" << std::endl; std::cout << "fpga sample counter module interrupt number " << irq_count << std::endl; } - - // it is a rising edge interrupt, the interrupt does not need to be acknowledged - //map_base[1] = 0; // writing anything to reg 1 acknowledges the interrupt - - // add number of passed samples or read the current counter value for more accuracy - counter = samples_per_output; //map_base[0]; - return counter; } diff --git a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h index a11a94be5..a715baeaf 100644 --- a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h +++ b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h @@ -50,11 +50,15 @@ private: void close_device(void); void open_device(void); bool start(); + bool stop(); - uint32_t wait_for_interrupt_and_read_counter(void); + void wait_for_interrupt(void); uint32_t samples_per_output; + uint32_t samples_per_report; double fs; uint64_t sample_counter; + uint64_t last_sample_counter; + uint32_t interval_ms; uint64_t current_T_rx_ms; // Receiver time in ms since the beginning of the run uint32_t current_s; // Receiver time in seconds, modulo 60 @@ -65,6 +69,7 @@ private: bool flag_days; // True if the receiver has been running for at least 1 day uint32_t current_days; // Receiver time in days since the beginning of the run int32_t report_interval_ms; + bool flag_enable_send_msg; int32_t fd; // driver descriptor volatile uint32_t *map_base; // driver memory map