1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-16 05:00:35 +00:00

updated the SW to run the new Acquisition HW accelerator, which compensates the scaling factors of the FFT and the IFFT, and computes the test statistics out of the peak value and the second peak value resulting from the correlation performed by the acquisition process. Updated the GPS L1 and Galileo E1 acquisition adapters.

This commit is contained in:
Marc Majoral 2018-10-31 18:48:08 +01:00
parent 17ddab1c3e
commit b5409f0860
7 changed files with 262 additions and 98 deletions

View File

@ -113,7 +113,7 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
//printf("acq adapter code_length = %d\n", code_length); //printf("acq adapter code_length = %d\n", code_length);
acq_parameters.code_length = code_length; acq_parameters.code_length = code_length;
// The FPGA can only use FFT lengths that are a power of two. // The FPGA can only use FFT lengths that are a power of two.
float nbits = ceilf(log2f((float)code_length)); float nbits = ceilf(log2f((float)code_length*2));
unsigned int nsamples_total = pow(2, nbits); unsigned int nsamples_total = pow(2, nbits);
unsigned int vector_length = nsamples_total; unsigned int vector_length = nsamples_total;
//printf("acq adapter nsamples_total (= vector_length) = %d\n", vector_length); //printf("acq adapter nsamples_total (= vector_length) = %d\n", vector_length);
@ -124,6 +124,7 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
acq_parameters.device_name = device_name; acq_parameters.device_name = device_name;
acq_parameters.samples_per_ms = nsamples_total/sampled_ms; acq_parameters.samples_per_ms = nsamples_total/sampled_ms;
acq_parameters.samples_per_code = nsamples_total; 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 upon the class constructor in order to avoid re-computing the PRN codes every time
// a channel is assigned) // a channel is assigned)
@ -178,9 +179,15 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
// } // }
// fclose(fid); // 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 = code_length; s < nsamples_total; s++) for (int s = 2*code_length; s < nsamples_total; s++)
{ {
code[s] = std::complex<float>(static_cast<float>(0,0)); code[s] = std::complex<float>(static_cast<float>(0,0));
//code[s] = 0; //code[s] = 0;
@ -226,8 +233,8 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
// static_cast<int>(floor(256*fft_codes_padded[i].imag() * (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)), // 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))); // 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, 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, 5) - 1) / max)),
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 5) - 1) / max)));
// tmp_re = static_cast<int>(floor(fft_codes_padded[i].real() * (pow(2, 7) - 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)); // tmp_im = static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max));
@ -292,6 +299,8 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
delete fft_if; delete fft_if;
delete[] fft_codes_padded; delete[] fft_codes_padded;
acq_parameters.total_block_exp = 11;
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";

View File

@ -81,7 +81,7 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
acq_parameters.code_length = code_length; acq_parameters.code_length = code_length;
//printf("acq adapter code_length = %d\n", code_length); //printf("acq adapter code_length = %d\n", code_length);
// The FPGA can only use FFT lengths that are a power of two. // The FPGA can only use FFT lengths that are a power of two.
float nbits = ceilf(log2f((float)code_length)); float nbits = ceilf(log2f((float)code_length*2));
unsigned int nsamples_total = pow(2, nbits); unsigned int nsamples_total = pow(2, nbits);
unsigned int vector_length = nsamples_total; unsigned int vector_length = nsamples_total;
//printf("acq adapter vector_length = %d\n", vector_length); //printf("acq adapter vector_length = %d\n", vector_length);
@ -94,7 +94,8 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
acq_parameters.samples_per_ms = nsamples_total / sampled_ms; acq_parameters.samples_per_ms = nsamples_total / sampled_ms;
//printf("acq adapter samples_per_ms = %d\n", 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.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 // 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) // a channel is assigned)
gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT
@ -106,12 +107,20 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
{ {
gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code
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 = code_length; s < nsamples_total; s++) for (int s = 2*code_length; s < nsamples_total; s++)
{ {
code[s] = std::complex<float>(static_cast<float>(0, 0)); code[s] = std::complex<float>(static_cast<float>(0, 0));
//code[s] = 0; //code[s] = 0;
} }
int offset = 0; int offset = 0;
memcpy(fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer memcpy(fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer
fft_if->execute(); // Run the FFT of local code fft_if->execute(); // Run the FFT of local code
@ -150,8 +159,8 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
// static_cast<int>(16*floor(fft_codes_padded[i].imag() * (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)), //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))); // 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, 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, 5) - 1) / max)),
static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); static_cast<int>(floor(fft_codes_padded[i].imag() * (pow(2, 5) - 1) / max)));
} }
@ -176,6 +185,8 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
delete fft_if; delete fft_if;
delete[] fft_codes_padded; delete[] fft_codes_padded;
acq_parameters.total_block_exp = 0;
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")";

View File

@ -59,6 +59,12 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga(
long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); 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); long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
float downsampling_factor = configuration_->property("GNSS-SDR.downsampling_factor", 1.0);
acq_parameters.downsampling_factor = downsampling_factor;
fs_in = fs_in/downsampling_factor;
acq_parameters.fs_in = fs_in; acq_parameters.fs_in = fs_in;
//if_ = configuration_->property(role + ".if", 0); //if_ = configuration_->property(role + ".if", 0);
//acq_parameters.freq = if_; //acq_parameters.freq = if_;

View File

@ -43,6 +43,7 @@
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include "pcps_acquisition_fpga.h" #include "pcps_acquisition_fpga.h"
#include <unistd.h> // for the usleep function only (debug)
#define AQ_DOWNSAMPLING_DELAY 40 // delay due to the downsampling filter in the acquisition #define AQ_DOWNSAMPLING_DELAY 40 // delay due to the downsampling filter in the acquisition
@ -89,14 +90,18 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_) : gr::block(
// (acq_parameters.device_name, acq_parameters.code_length, acq_parameters.doppler_max, acq_parameters.samples_per_ms, // (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); // 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 // 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, 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.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> // 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.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); // acq_parameters.fs_in, acq_parameters.freq, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes);
// debug // debug
//debug_d_max_absolute = 0.0; //debug_d_max_absolute = 0.0;
//debug_d_input_power_absolute = 0.0; //debug_d_input_power_absolute = 0.0;
@ -211,13 +216,16 @@ void pcps_acquisition_fpga::send_negative_acquisition()
void pcps_acquisition_fpga::set_active(bool active) void pcps_acquisition_fpga::set_active(bool active)
{ {
// printf("acq set active start\n"); // printf("acq set active start\n");
d_active = active; d_active = active;
// initialize acquisition algorithm // initialize acquisition algorithm
uint32_t indext = 0U; uint32_t indext = 0U;
float magt = 0.0; float firstpeak = 0.0;
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size); 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_input_power = 0.0;
d_mag = 0.0; d_mag = 0.0;
@ -236,73 +244,60 @@ void pcps_acquisition_fpga::set_active(bool active)
float temp_d_input_power; float temp_d_input_power;
// loop through acquisition
/*
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
{
// doppler search steps
int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
//acquisition_fpga->set_phase_step(doppler_index);
acquisition_fpga->set_doppler_sweep_debug(1, doppler_index);
acquisition_fpga->run_acquisition(); // runs acquisition and waits until it is finished
acquisition_fpga->read_acquisition_results(&indext, &magt,
&initial_sample, &d_input_power, &d_doppler_index);
d_sample_counter = initial_sample;
if (d_mag < magt)
{
d_mag = magt;
temp_d_input_power = d_input_power;
input_power_all = d_input_power / (d_fft_size - 1);
input_power_computed = (d_input_power - d_mag) / (d_fft_size - 1);
d_input_power = (d_input_power - d_mag) / (d_fft_size - 1);
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code);
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
d_test_statistics = (d_mag / d_input_power); //* correction_factor;
}
// In the case of the FPGA the option of dumping the results of the acquisition to a file is not available
// because the IFFT vector is not available
}
*/
// debug // debug
//acquisition_fpga->block_samples(); //acquisition_fpga->block_samples();
// while(1)
//{
// run loop in hw // run loop in hw
//printf("LAUNCH ACQ\n"); //printf("LAUNCH ACQ\n");
//printf("acq lib d_num_doppler_bins = %d\n", d_num_doppler_bins); //printf("acq lib d_num_doppler_bins = %d\n", d_num_doppler_bins);
//printf("writing config for channel %d -----------------------------------------\n", (int) d_channel);
acquisition_fpga->configure_acquisition();
acquisition_fpga->set_doppler_sweep(d_num_doppler_bins); acquisition_fpga->set_doppler_sweep(d_num_doppler_bins);
acquisition_fpga->write_local_code();
//acquisition_fpga->set_doppler_sweep(2); //acquisition_fpga->set_doppler_sweep(2);
//printf("acq lib going to launch acquisition\n"); //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(); acquisition_fpga->run_acquisition();
//printf("acq lib going to read the acquisition results\n"); //printf("acq lib going to read the acquisition results\n");
acquisition_fpga->read_acquisition_results(&indext, &magt, //read_acquisition_results(&indext, &firstpeak, &secondpeak, &initial_sample, &d_input_power, &d_doppler_index);
&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("gnuradio block : d_total_block_exp = %d total_block_exp = %d\n", (int) d_total_block_exp, (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);
d_total_block_exp = total_block_exp;
}
//printf("end channel %d -----------------------------------------------------\n", (int) d_channel);
//printf("READ ACQ RESULTS\n"); //printf("READ ACQ RESULTS\n");
// debug // debug
//acquisition_fpga->unblock_samples(); //acquisition_fpga->unblock_samples();
d_mag = magt;
//usleep(5000000);
//} // end while test
// 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; int32_t doppler;
// NEW SATELLITE DETECTION ALGORITHM STARTS HERE ----------------------------------------------------
if (d_single_doppler_flag == false) 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 - 1);
@ -312,10 +307,46 @@ void pcps_acquisition_fpga::set_active(bool active)
{ {
doppler = static_cast<int32_t>(acq_parameters.doppler_max); 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)));
if (secondpeak > 0)
{
d_test_statistics = firstpeak/secondpeak;
}
else
{
d_test_statistics = 0.0;
}
//printf("acq gnuradioblock doppler = %d\n", doppler); // // 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_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_sample_counter = initial_sample; d_sample_counter = initial_sample;
@ -355,7 +386,13 @@ void pcps_acquisition_fpga::set_active(bool active)
//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 = 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 //d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter - 40; // delay due to the downsampling filter in the acquisition
d_test_statistics = (d_mag / d_input_power); //* correction_factor; // // OLD SATELLITE DETECTION ALGORITHM STARTS HERE AGAIN -----------------------------------------------
//
// d_test_statistics = (d_mag / d_input_power); //* correction_factor;
//
// // END OF OLD SATELLITE ALGORITHM AGAIN --------------------------------------------------------------------
// debug // debug
// if (d_gnss_synchro->Acq_delay_samples > acq_parameters.code_length) // if (d_gnss_synchro->Acq_delay_samples > acq_parameters.code_length)
@ -400,6 +437,7 @@ void pcps_acquisition_fpga::set_active(bool active)
send_negative_acquisition(); send_negative_acquisition();
} }
//printf("acq set active end\n"); //printf("acq set active end\n");
} }
@ -425,8 +463,8 @@ void pcps_acquisition_fpga::set_single_doppler_flag(unsigned int single_doppler_
void pcps_acquisition_fpga::read_acquisition_results(uint32_t *max_index, void pcps_acquisition_fpga::read_acquisition_results(uint32_t *max_index,
float *max_magnitude, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index) float *max_magnitude, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index)
{ {
acquisition_fpga->read_acquisition_results(max_index, max_magnitude, // acquisition_fpga->read_acquisition_results(max_index, max_magnitude,
initial_sample, power_sum, doppler_index); // initial_sample, power_sum, doppler_index);
} }
// this function is only used for the unit tests // this function is only used for the unit tests
@ -439,3 +477,6 @@ void pcps_acquisition_fpga::read_fpga_total_scale_factor(uint32_t *total_scale_f
{ {
acquisition_fpga->read_fpga_total_scale_factor(total_scale_factor, fw_scale_factor); acquisition_fpga->read_fpga_total_scale_factor(total_scale_factor, fw_scale_factor);
} }

View File

@ -74,6 +74,8 @@ typedef struct
std::string device_name; std::string device_name;
lv_16sc_t* all_fft_codes; // memory that contains all the code ffts lv_16sc_t* all_fft_codes; // memory that contains all the code ffts
float downsampling_factor; float downsampling_factor;
uint32_t total_block_exp;
uint32_t excludelimit;
} pcpsconf_fpga_t; } pcpsconf_fpga_t;
class pcps_acquisition_fpga; class pcps_acquisition_fpga;
@ -102,6 +104,8 @@ private:
void send_positive_acquisition(); void send_positive_acquisition();
float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
pcpsconf_fpga_t acq_parameters; pcpsconf_fpga_t acq_parameters;
bool d_active; bool d_active;
float d_threshold; float d_threshold;
@ -128,6 +132,8 @@ private:
uint32_t d_select_queue_Fpga; uint32_t d_select_queue_Fpga;
bool d_single_doppler_flag; bool d_single_doppler_flag;
uint32_t d_total_block_exp;
public: public:
~pcps_acquisition_fpga(); ~pcps_acquisition_fpga();

View File

@ -41,6 +41,9 @@
#include <fcntl.h> // libraries used by the GIPO #include <fcntl.h> // libraries used by the GIPO
#include <sys/mman.h> // libraries used by the GIPO #include <sys/mman.h> // libraries used by the GIPO
#include <unistd.h> // for the usleep function only (debug)
#define PAGE_SIZE 0x10000 // default page size for the multicorrelator memory map #define PAGE_SIZE 0x10000 // default page size for the multicorrelator memory map
#define MAX_PHASE_STEP_RAD 0.999999999534339 // 1 - pow(2,-31); #define MAX_PHASE_STEP_RAD 0.999999999534339 // 1 - pow(2,-31);
@ -72,7 +75,7 @@ bool fpga_acquisition::init()
{ {
//printf("acq lib init called\n"); //printf("acq lib init called\n");
// configure the acquisition with the main initialization values // configure the acquisition with the main initialization values
fpga_acquisition::configure_acquisition(); //fpga_acquisition::configure_acquisition();
return true; return true;
} }
@ -81,8 +84,11 @@ bool fpga_acquisition::set_local_code(uint32_t PRN)
{ {
//printf("acq lib set_local_code_called\n"); //printf("acq lib set_local_code_called\n");
// select the code with the chosen PRN // select the code with the chosen PRN
fpga_acquisition::fpga_configure_acquisition_local_code( d_PRN = PRN;
&d_all_fft_codes[d_nsamples_total * (PRN - 1)]); // 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( //fpga_acquisition::fpga_configure_acquisition_local_code(
// &d_all_fft_codes[0]); // &d_all_fft_codes[0]);
@ -91,12 +97,22 @@ bool fpga_acquisition::set_local_code(uint32_t PRN)
} }
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)]);
}
fpga_acquisition::fpga_acquisition(std::string device_name, fpga_acquisition::fpga_acquisition(std::string device_name,
uint32_t nsamples, uint32_t nsamples,
uint32_t doppler_max, uint32_t doppler_max,
uint32_t nsamples_total, int64_t fs_in, uint32_t nsamples_total, int64_t fs_in,
uint32_t sampled_ms, uint32_t select_queue, uint32_t sampled_ms, uint32_t select_queue,
lv_16sc_t *all_fft_codes) lv_16sc_t *all_fft_codes,
uint32_t excludelimit)
{ {
//printf("acq lib constructor called\n"); //printf("acq lib constructor called\n");
//printf("AAA- sampled_ms = %d\n ", sampled_ms); //printf("AAA- sampled_ms = %d\n ", sampled_ms);
@ -109,6 +125,7 @@ fpga_acquisition::fpga_acquisition(std::string device_name,
//d_freq = freq; //d_freq = freq;
d_fs_in = fs_in; d_fs_in = fs_in;
d_vector_length = vector_length; d_vector_length = vector_length;
d_excludelimit = excludelimit;
d_nsamples = nsamples; // number of samples not including padding d_nsamples = nsamples; // number of samples not including padding
d_select_queue = select_queue; d_select_queue = select_queue;
d_nsamples_total = nsamples_total; d_nsamples_total = nsamples_total;
@ -160,6 +177,7 @@ fpga_acquisition::fpga_acquisition(std::string device_name,
// flag used for testing purposes // flag used for testing purposes
d_single_doppler_flag = 0; d_single_doppler_flag = 0;
d_PRN = 0;
DLOG(INFO) << "Acquisition FPGA class created"; DLOG(INFO) << "Acquisition FPGA class created";
} }
@ -228,26 +246,46 @@ void fpga_acquisition::fpga_configure_acquisition_local_code(lv_16sc_t fft_local
void fpga_acquisition::run_acquisition(void) void fpga_acquisition::run_acquisition(void)
{ {
//printf("acq lib run_acqisition called\n"); //printf("acq lib run_acqisition called\n");
// enable interrupts // enable interrupts
int32_t reenable = 1; //int32_t reenable = 1;
write(d_fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t)); //reenable = 1;
//write(d_fd, reinterpret_cast<void *>(&reenable), sizeof(int32_t));
// launch the acquisition process // launch the acquisition process
//printf("acq lib launchin acquisition ...\n"); //printf("acq lib launchin acquisition ...\n");
d_map_base[8] = LAUNCH_ACQUISITION; // writing a 1 to reg 8 launches the acquisition process d_map_base[8] = LAUNCH_ACQUISITION; // writing a 1 to reg 8 launches the acquisition process
//printf("acq lib waiting for interrupt ...\n"); //printf("acq lib waiting for interrupt ...\n");
int32_t irq_count; int32_t irq_count;
ssize_t nb; ssize_t nb;
// wait for interrupt
nb = read(d_fd, &irq_count, sizeof(irq_count)); uint32_t result_valid = 0;
//printf("interrupt received\n");
if (nb != sizeof(irq_count)) usleep(50);
while(result_valid == 0)
{ {
printf("acquisition module Read failed to retrieve 4 bytes!\n"); read_result_valid(&result_valid); // polling
printf("acquisition module Interrupt number %d\n", irq_count);
} }
// 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);
// }
} }
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) void fpga_acquisition::set_doppler_sweep(uint32_t num_sweeps)
{ {
@ -292,7 +330,7 @@ void fpga_acquisition::set_doppler_sweep(uint32_t num_sweeps)
//printf("AAA phase_step_rad_real for doppler step after checking = %f\n", phase_step_rad_real); //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_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 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); //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; d_map_base[4] = phase_step_rad_int;
//printf("AAA writing num sweeps to d map base 5 = %d\n", num_sweeps); //printf("AAA writing num sweeps to d map base 5 = %d\n", num_sweeps);
d_map_base[5] = num_sweeps; d_map_base[5] = num_sweeps;
@ -406,6 +444,9 @@ void fpga_acquisition::configure_acquisition()
d_map_base[2] = 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)); //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 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", d_vector_length);
//printf("acquisition debug vector length = %d\n", (int)log2((float)d_vector_length)); //printf("acquisition debug vector length = %d\n", (int)log2((float)d_vector_length));
} }
@ -435,39 +476,65 @@ void fpga_acquisition::set_phase_step(uint32_t doppler_index)
//printf("AAA+ phase_step_rad_real after checking = %f\n", phase_step_rad_real); //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_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 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\n", phase_step_rad_int); //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; d_map_base[3] = phase_step_rad_int;
} }
void fpga_acquisition::read_acquisition_results(uint32_t *max_index, void fpga_acquisition::read_acquisition_results(uint32_t *max_index,
float *max_magnitude, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index) float *firstpeak, float *secondpeak, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index, uint32_t *total_blk_exp)
{ {
//printf("acq lib read_acquisition_results_called\n"); //printf("acq lib read_acquisition_results_called\n");
uint64_t initial_sample_tmp = 0; uint64_t initial_sample_tmp = 0;
uint32_t readval = 0; uint32_t readval = 0;
uint64_t readval_long = 0; uint64_t readval_long = 0;
uint64_t readval_long_shifted = 0; uint64_t readval_long_shifted = 0;
readval = d_map_base[1]; readval = d_map_base[1];
initial_sample_tmp = readval; initial_sample_tmp = readval;
readval_long = d_map_base[2]; readval_long = d_map_base[2];
readval_long_shifted = readval_long << 32; // 2^32 readval_long_shifted = readval_long << 32; // 2^32
initial_sample_tmp = initial_sample_tmp + readval_long_shifted; // 2^32 initial_sample_tmp = initial_sample_tmp + readval_long_shifted; // 2^32
//printf("----------------------------------------------------------------> acq initial sample TOTAL = %llu\n", initial_sample_tmp);
*initial_sample = initial_sample_tmp; *initial_sample = initial_sample_tmp;
readval = d_map_base[6]; //printf("-------> acq initial sample TOTAL = %llu\n", *initial_sample);
*max_magnitude = static_cast<float>(readval);
//printf("acq lib read max_magnitude dmap 2 = %d = %f\n", readval, *max_magnitude);
readval = d_map_base[4];
*power_sum = static_cast<float>(readval);
//printf("acq lib read power sum dmap 4 = %d = %f\n", readval, *power_sum);
readval = d_map_base[5]; // read doppler index
*doppler_index = readval;
//printf("read doppler_index dmap 5 = %d\n", readval);
readval = d_map_base[3]; 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; *max_index = readval;
//printf("read max index dmap 3 = %d\n", 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
} }
@ -513,8 +580,16 @@ void fpga_acquisition::set_single_doppler_flag(unsigned int single_doppler_flag)
void fpga_acquisition::read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor) void fpga_acquisition::read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor)
{ {
uint32_t readval = 0; uint32_t readval = 0;
readval = d_map_base[7];
*total_scale_factor = readval;
readval = d_map_base[8]; readval = d_map_base[8];
*fw_scale_factor = readval; *total_scale_factor = readval;
//readval = d_map_base[8];
*fw_scale_factor = 0;
}
void fpga_acquisition::read_result_valid(uint32_t *result_valid)
{
uint32_t readval = 0;
readval = d_map_base[0];
*result_valid = readval;
} }

View File

@ -53,7 +53,8 @@ public:
int64_t fs_in, int64_t fs_in,
uint32_t sampled_ms, uint32_t sampled_ms,
uint32_t select_queue, uint32_t select_queue,
lv_16sc_t *all_fft_codes); lv_16sc_t *all_fft_codes,
uint32_t excludelimit);
~fpga_acquisition(); ~fpga_acquisition();
bool init(); bool init();
@ -63,8 +64,11 @@ public:
//void set_doppler_sweep_debug(uint32_t num_sweeps, uint32_t doppler_index); //void set_doppler_sweep_debug(uint32_t num_sweeps, uint32_t doppler_index);
void run_acquisition(void); void run_acquisition(void);
void set_phase_step(uint32_t doppler_index); void set_phase_step(uint32_t doppler_index);
void read_acquisition_results(uint32_t *max_index, float *max_magnitude, //void read_acquisition_results(uint32_t *max_index, float *max_magnitude,
uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index); // 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 block_samples();
void unblock_samples(); void unblock_samples();
@ -105,6 +109,14 @@ public:
*/ */
void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor);
void set_block_exp(uint32_t total_block_exp);
void write_local_code(void);
void configure_acquisition(void);
private: private:
int64_t d_fs_in; int64_t d_fs_in;
// data related to the hardware module and the driver // data related to the hardware module and the driver
@ -112,18 +124,22 @@ private:
volatile uint32_t *d_map_base; // driver memory map volatile uint32_t *d_map_base; // driver memory map
lv_16sc_t *d_all_fft_codes; // memory that contains all the code ffts lv_16sc_t *d_all_fft_codes; // memory that contains all the code ffts
uint32_t d_vector_length; // number of samples incluing padding and number of ms uint32_t d_vector_length; // number of samples incluing padding and number of ms
uint32_t d_excludelimit;
uint32_t d_nsamples_total; // number of samples including padding uint32_t d_nsamples_total; // number of samples including padding
uint32_t d_nsamples; // number of samples not including padding uint32_t d_nsamples; // number of samples not including padding
uint32_t d_select_queue; // queue selection uint32_t d_select_queue; // queue selection
std::string d_device_name; // HW device name std::string d_device_name; // HW device name
uint32_t d_doppler_max; // max doppler uint32_t d_doppler_max; // max doppler
uint32_t d_doppler_step; // doppler step uint32_t d_doppler_step; // doppler step
uint32_t d_PRN; // PRN
// FPGA private functions // FPGA private functions
uint32_t fpga_acquisition_test_register(uint32_t writeval); uint32_t fpga_acquisition_test_register(uint32_t writeval);
void fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]); void fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]);
void configure_acquisition(); //void configure_acquisition();
void close_device(); void close_device();
void read_result_valid(uint32_t *result_valid);
// test parameters // test parameters
unsigned int d_single_doppler_flag; // this flag is only used for testing purposes unsigned int d_single_doppler_flag; // this flag is only used for testing purposes
}; };