mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-20 22:17:03 +00:00
The switch bug is solved. Now the switch uses an absolute sample counter
This commit is contained in:
parent
ea86546d99
commit
a9c7b4113b
@ -1,12 +1,13 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file gnss_sdr_fpga_sample_counter.cc
|
* \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
|
* \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
|
* \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
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
* Satellite Systems receiver
|
* Satellite Systems receiver
|
||||||
@ -54,19 +55,16 @@ gnss_sdr_fpga_sample_counter::gnss_sdr_fpga_sample_counter(
|
|||||||
interval_ms = _interval_ms;
|
interval_ms = _interval_ms;
|
||||||
fs = _fs;
|
fs = _fs;
|
||||||
samples_per_output = std::round(fs * static_cast<double>(interval_ms) / 1e3);
|
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 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();
|
open_device();
|
||||||
|
|
||||||
sample_counter = 0ULL;
|
sample_counter = 0ULL;
|
||||||
|
last_sample_counter = 0ULL;
|
||||||
current_T_rx_ms = 0;
|
current_T_rx_ms = 0;
|
||||||
current_s = 0;
|
current_s = 0;
|
||||||
current_m = 0;
|
current_m = 0;
|
||||||
current_h = 0;
|
current_h = 0;
|
||||||
current_days = 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<double>(report_interval_ms) / 1e3);
|
||||||
flag_enable_send_msg = false; // enable it for reporting time with asynchronous message
|
flag_enable_send_msg = false; // enable it for reporting time with asynchronous message
|
||||||
flag_m = false;
|
flag_m = false;
|
||||||
flag_h = 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.
|
// Called by gnuradio to enable drivers, etc for i/o devices.
|
||||||
bool gnss_sdr_fpga_sample_counter::start()
|
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 the number of samples per output in the FPGA and enable the interrupts
|
||||||
configure_samples_per_output(samples_per_output);
|
configure_samples_per_output(samples_per_output);
|
||||||
|
|
||||||
@ -93,14 +89,12 @@ bool gnss_sdr_fpga_sample_counter::start()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Called by GNURadio to disable drivers, etc for i/o devices.
|
// Called by GNURadio to disable drivers, etc for i/o devices.
|
||||||
bool gnss_sdr_fpga_sample_counter::stop()
|
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();
|
close_device();
|
||||||
|
|
||||||
|
// return true if everything is ok.
|
||||||
return true;
|
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,
|
__attribute__((unused)) gr_vector_const_void_star &input_items,
|
||||||
gr_vector_void_star &output_items)
|
gr_vector_void_star &output_items)
|
||||||
{
|
{
|
||||||
//todo: Call here a function that waits for an interrupt. Do not open a thread,
|
wait_for_interrupt();
|
||||||
//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.
|
|
||||||
|
|
||||||
uint32_t counter = wait_for_interrupt_and_read_counter();
|
uint64_t sample_counter_tmp, sample_counter_msw_tmp;
|
||||||
uint64_t samples_passed = 2 * static_cast<uint64_t>(samples_per_output) - static_cast<uint64_t>(counter); // ellapsed samples
|
sample_counter_tmp = map_base[0];
|
||||||
// Note: at this moment the sample counter is implemented as a sample counter that decreases to zero and then it is automatically
|
sample_counter_msw_tmp = map_base[1];
|
||||||
// reloaded again and keeps counter. It is done in this way to minimize the logic in the FPGA and maximize the FPGA clock performance
|
sample_counter_msw_tmp = sample_counter_msw_tmp << 32;
|
||||||
// (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
|
sample_counter_tmp = sample_counter_tmp + sample_counter_msw_tmp; // 2^32
|
||||||
// variable number).
|
sample_counter = sample_counter_tmp;
|
||||||
|
|
||||||
sample_counter = sample_counter + samples_passed; //samples_per_output;
|
|
||||||
auto *out = reinterpret_cast<Gnss_Synchro *>(output_items[0]);
|
auto *out = reinterpret_cast<Gnss_Synchro *>(output_items[0]);
|
||||||
out[0] = Gnss_Synchro();
|
out[0] = Gnss_Synchro();
|
||||||
out[0].Flag_valid_symbol_output = false;
|
out[0].Flag_valid_symbol_output = false;
|
||||||
out[0].Flag_valid_word = false;
|
out[0].Flag_valid_word = false;
|
||||||
out[0].Channel_ID = -1;
|
out[0].Channel_ID = -1;
|
||||||
out[0].fs = fs;
|
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++;
|
current_s++;
|
||||||
if ((current_s % 60) == 0)
|
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;
|
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;
|
current_T_rx_ms = interval_ms * (sample_counter) / samples_per_output;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -240,7 +231,6 @@ void gnss_sdr_fpga_sample_counter::open_device()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(INFO) << "Acquisition test register sanity check success!";
|
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);
|
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;
|
int32_t irq_count;
|
||||||
ssize_t nb;
|
ssize_t nb;
|
||||||
int32_t counter;
|
|
||||||
|
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
int32_t reenable = 1;
|
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 read failed to retrieve 4 bytes!" << std::endl;
|
||||||
std::cout << "fpga sample counter module interrupt number " << irq_count << 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;
|
|
||||||
}
|
}
|
||||||
|
@ -50,11 +50,15 @@ private:
|
|||||||
void close_device(void);
|
void close_device(void);
|
||||||
void open_device(void);
|
void open_device(void);
|
||||||
bool start();
|
bool start();
|
||||||
|
|
||||||
bool stop();
|
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_output;
|
||||||
|
uint32_t samples_per_report;
|
||||||
double fs;
|
double fs;
|
||||||
uint64_t sample_counter;
|
uint64_t sample_counter;
|
||||||
|
uint64_t last_sample_counter;
|
||||||
|
|
||||||
uint32_t interval_ms;
|
uint32_t interval_ms;
|
||||||
uint64_t current_T_rx_ms; // Receiver time in ms since the beginning of the run
|
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
|
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
|
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
|
uint32_t current_days; // Receiver time in days since the beginning of the run
|
||||||
int32_t report_interval_ms;
|
int32_t report_interval_ms;
|
||||||
|
|
||||||
bool flag_enable_send_msg;
|
bool flag_enable_send_msg;
|
||||||
int32_t fd; // driver descriptor
|
int32_t fd; // driver descriptor
|
||||||
volatile uint32_t *map_base; // driver memory map
|
volatile uint32_t *map_base; // driver memory map
|
||||||
|
Loading…
Reference in New Issue
Block a user