1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-06-26 06:53:14 +00:00

Merge branch 'fpga_extended_coherent_integration' of https://github.com/mmajoral/gnss-sdr into mmajoral-fpga_extended_coherent_integration

This commit is contained in:
Carles Fernandez 2019-07-26 13:12:46 +02:00
commit d626ca1f88
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
34 changed files with 1751 additions and 1014 deletions

View File

@ -44,14 +44,6 @@
#include <cmath> // for abs, pow, floor
#include <complex> // for complex
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
#define QUANT_BITS_LOCAL_CODE 16
#define SELECT_LSBits 0x0000FFFF // Select the 10 LSbits out of a 20-bit word
#define SELECT_MSBbits 0xFFFF0000 // Select the 10 MSbits out of a 20-bit word
#define SELECT_ALL_CODE_BITS 0xFFFFFFFF // Select a 20 bit word
#define SHL_CODE_BITS 65536 // shift left by 10 bits
GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
ConfigurationInterface* configuration,
const std::string& role,
@ -166,10 +158,10 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
// and package codes in a format that is ready to be written to the FPGA
for (uint32_t i = 0; i < nsamples_total; i++)
{
tmp = static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max));
tmp2 = static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max));
local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part
fft_data = local_code & SELECT_ALL_CODE_BITS;
tmp = static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, quant_bits_local_code - 1) - 1) / max));
tmp2 = static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, quant_bits_local_code - 1) - 1) / max));
local_code = (tmp & select_lsbits) | ((tmp2 * shl_code_bits) & select_msbits); // put together the real part and the imaginary part
fft_data = local_code & select_all_code_bits;
d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data;
}
}
@ -221,6 +213,12 @@ void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_step(unsigned int dopple
acquisition_fpga_->set_doppler_step(doppler_step_);
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_center(int doppler_center)
{
doppler_center_ = doppler_center;
acquisition_fpga_->set_doppler_center(doppler_center_);
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
{

View File

@ -24,7 +24,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -32,16 +32,15 @@
#ifndef GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_
#define GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_
#include "acq_conf.h"
#include "channel_fsm.h"
#include "gnss_synchro.h"
#include "pcps_acquisition_fpga.h"
#include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr
#include <volk/volk_complex.h> // for lv_16sc_t
#include <cstddef> // for size_t
#include <memory>
#include <string>
#include <vector>
class Gnss_Synchro;
class ConfigurationInterface;
/*!
@ -51,13 +50,22 @@ class ConfigurationInterface;
class GalileoE1PcpsAmbiguousAcquisitionFpga : public AcquisitionInterface
{
public:
/*!
* \brief Constructor
*/
GalileoE1PcpsAmbiguousAcquisitionFpga(ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams);
/*!
* \brief Destructor
*/
~GalileoE1PcpsAmbiguousAcquisitionFpga() = default;
/*!
* \brief Role
*/
inline std::string role() override
{
return role_;
@ -71,21 +79,38 @@ public:
return "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga";
}
/*!
* \brief Returns size of lv_16sc_t
*/
size_t item_size() override
{
size_t item_size = sizeof(lv_16sc_t);
return item_size;
return sizeof(int16_t);
}
/*!
* \brief Connect
*/
void connect(gr::top_block_sptr top_block) override;
/*!
* \brief Disconnect
*/
void disconnect(gr::top_block_sptr top_block) override;
/*!
* \brief Get left block
*/
gr::basic_block_sptr get_left_block() override;
/*!
* \brief Get right block
*/
gr::basic_block_sptr get_right_block() override;
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to efficiently exchange synchronization data between acquisition and
* tracking blocks
* tracking blocks
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
@ -122,6 +147,11 @@ public:
*/
void set_doppler_step(unsigned int doppler_step) override;
/*!
* \brief Set Doppler center for the grid search
*/
void set_doppler_center(int doppler_center) override;
/*!
* \brief Initializes acquisition algorithm.
*/
@ -152,9 +182,20 @@ public:
*/
void stop_acquisition() override;
/*!
* \brief Set resampler latency
*/
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
static const uint32_t quant_bits_local_code = 16;
static const uint32_t select_lsbits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word
static const uint32_t select_msbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word
static const uint32_t select_all_code_bits = 0xFFFFFFFF; // Select a 20 bit word
static const uint32_t shl_code_bits = 65536; // shift left by 10 bits
ConfigurationInterface* configuration_;
pcps_acquisition_fpga_sptr acquisition_fpga_;
bool acquire_pilot_;
@ -162,6 +203,7 @@ private:
std::weak_ptr<ChannelFsm> channel_fsm_;
uint32_t doppler_max_;
uint32_t doppler_step_;
int32_t doppler_center_;
std::string dump_filename_;
Gnss_Synchro* gnss_synchro_;
std::string role_;

View File

@ -44,14 +44,6 @@
#include <cmath> // for abs, pow, floor
#include <complex> // for complex
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
#define QUANT_BITS_LOCAL_CODE 16
#define SELECT_LSBits 0x0000FFFF // Select the 10 LSbits out of a 20-bit word
#define SELECT_MSBbits 0xFFFF0000 // Select the 10 MSbits out of a 20-bit word
#define SELECT_ALL_CODE_BITS 0xFFFFFFFF // Select a 20 bit word
#define SHL_CODE_BITS 65536 // shift left by 10 bits
GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
@ -169,10 +161,10 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
// and package codes in a format that is ready to be written to the FPGA
for (uint32_t i = 0; i < nsamples_total; i++)
{
tmp = static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max));
tmp2 = static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max));
local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part
fft_data = local_code & SELECT_ALL_CODE_BITS;
tmp = static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, quant_bits_local_code - 1) - 1) / max));
tmp2 = static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, quant_bits_local_code - 1) - 1) / max));
local_code = (tmp & select_lsbits) | ((tmp2 * shl_code_bits) & select_msbits); // put together the real part and the imaginary part
fft_data = local_code & select_all_code_bits;
d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data;
}
}
@ -224,6 +216,12 @@ void GalileoE5aPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
acquisition_fpga_->set_doppler_step(doppler_step_);
}
void GalileoE5aPcpsAcquisitionFpga::set_doppler_center(int doppler_center)
{
doppler_center_ = doppler_center;
acquisition_fpga_->set_doppler_center(doppler_center_);
}
void GalileoE5aPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
{

View File

@ -24,7 +24,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -34,16 +34,12 @@
#include "channel_fsm.h"
#include "gnss_synchro.h"
#include "pcps_acquisition_fpga.h"
#include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr
#include <volk/volk_complex.h> // for lv_16sc_t
#include <cstddef> // for size_t
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
class Gnss_Synchro;
class ConfigurationInterface;
@ -54,13 +50,22 @@ class ConfigurationInterface;
class GalileoE5aPcpsAcquisitionFpga : public AcquisitionInterface
{
public:
/*!
* \brief Constructor
*/
GalileoE5aPcpsAcquisitionFpga(ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams);
/*!
* \brief Destructor
*/
~GalileoE5aPcpsAcquisitionFpga() = default;
/*!
* \brief Role
*/
inline std::string role() override
{
return role_;
@ -74,20 +79,38 @@ public:
return "Galileo_E5a_Pcps_Acquisition_Fpga";
}
/*!
* \brief Returns size of lv_16sc_t
*/
inline size_t item_size() override
{
return sizeof(lv_16sc_t);
return sizeof(int16_t);
}
/*!
* \brief Connect
*/
void connect(gr::top_block_sptr top_block) override;
/*!
* \brief Disconnect
*/
void disconnect(gr::top_block_sptr top_block) override;
/*!
* \brief Get left block
*/
gr::basic_block_sptr get_left_block() override;
/*!
* \brief Get right block
*/
gr::basic_block_sptr get_right_block() override;
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to efficiently exchange synchronization data between acquisition and
* tracking blocks
* tracking blocks
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
@ -124,6 +147,11 @@ public:
*/
void set_doppler_step(unsigned int doppler_step) override;
/*!
* \brief Set Doppler center for the grid search
*/
void set_doppler_center(int doppler_center) override;
/*!
* \brief Initializes acquisition algorithm.
*/
@ -162,11 +190,19 @@ public:
void stop_acquisition() override;
/*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation
* \brief Set resampler latency
*/
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
static const uint32_t quant_bits_local_code = 16;
static const uint32_t select_lsbits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word
static const uint32_t select_msbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word
static const uint32_t select_all_code_bits = 0xFFFFFFFF; // Select a 20 bit word
static const uint32_t shl_code_bits = 65536; // shift left by 10 bits
ConfigurationInterface* configuration_;
pcps_acquisition_fpga_sptr acquisition_fpga_;
std::string item_type_;
@ -178,6 +214,7 @@ private:
std::weak_ptr<ChannelFsm> channel_fsm_;
uint32_t doppler_max_;
uint32_t doppler_step_;
int32_t doppler_center_;
unsigned int in_streams_;
unsigned int out_streams_;
Gnss_Synchro* gnss_synchro_;

View File

@ -47,16 +47,6 @@
#include <cmath> // for abs, pow, floor
#include <complex> // for complex
#define NUM_PRNs 32
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
#define QUANT_BITS_LOCAL_CODE 16
#define SELECT_LSBits 0x0000FFFF // Select the 10 LSbits out of a 20-bit word
#define SELECT_MSBbits 0xFFFF0000 // Select the 10 MSbits out of a 20-bit word
#define SELECT_ALL_CODE_BITS 0xFFFFFFFF // Select a 20 bit word
#define SHL_CODE_BITS 65536 // shift left by 10 bits
GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
ConfigurationInterface* configuration,
const std::string& role,
@ -146,10 +136,10 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
// and package codes in a format that is ready to be written to the FPGA
for (uint32_t i = 0; i < nsamples_total; i++)
{
tmp = static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max));
tmp2 = static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max));
local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part
fft_data = local_code & SELECT_ALL_CODE_BITS;
tmp = static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, quant_bits_local_code - 1) - 1) / max));
tmp2 = static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, quant_bits_local_code - 1) - 1) / max));
local_code = (tmp & select_lsbits) | ((tmp2 * shl_code_bits) & select_msbits); // put together the real part and the imaginary part
fft_data = local_code & select_all_code_bits;
d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data;
}
}
@ -202,6 +192,12 @@ void GpsL1CaPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
acquisition_fpga_->set_doppler_step(doppler_step_);
}
void GpsL1CaPcpsAcquisitionFpga::set_doppler_center(int doppler_center)
{
doppler_center_ = doppler_center;
acquisition_fpga_->set_doppler_center(doppler_center_);
}
void GpsL1CaPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
{

View File

@ -38,14 +38,11 @@
#include "channel_fsm.h"
#include "pcps_acquisition_fpga.h"
#include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr
#include <volk/volk_complex.h> // for lv_16sc_t
#include <cstddef> // for size_t
#include <memory>
#include <string>
#include <vector>
class Gnss_Synchro;
class ConfigurationInterface;
/*!
@ -55,13 +52,22 @@ class ConfigurationInterface;
class GpsL1CaPcpsAcquisitionFpga : public AcquisitionInterface
{
public:
/*!
* \brief Constructor
*/
GpsL1CaPcpsAcquisitionFpga(ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams);
/*!
* \brief Destructor
*/
~GpsL1CaPcpsAcquisitionFpga() = default;
/*!
* \brief Role
*/
inline std::string role() override
{
return role_;
@ -75,15 +81,32 @@ public:
return "GPS_L1_CA_PCPS_Acquisition_Fpga";
}
/*!
* \brief Returns size of lv_16sc_t
*/
inline size_t item_size() override
{
size_t item_size = sizeof(lv_16sc_t);
return item_size;
return sizeof(int16_t);
}
/*!
* \brief Connect
*/
void connect(gr::top_block_sptr top_block) override;
/*!
* \brief Disconnect
*/
void disconnect(gr::top_block_sptr top_block) override;
/*!
* \brief Get left block
*/
gr::basic_block_sptr get_left_block() override;
/*!
* \brief Get right block
*/
gr::basic_block_sptr get_right_block() override;
/*!
@ -126,6 +149,11 @@ public:
*/
void set_doppler_step(unsigned int doppler_step) override;
/*!
* \brief Set Doppler center for the grid search
*/
void set_doppler_center(int doppler_center) override;
/*!
* \brief Initializes acquisition algorithm.
*/
@ -156,15 +184,30 @@ public:
*/
void stop_acquisition() override;
/*!
* \brief Set Resampler Latency
*/
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
static const uint32_t NUM_PRNs = 32;
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
static const uint32_t quant_bits_local_code = 16;
static const uint32_t select_lsbits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word
static const uint32_t select_msbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word
static const uint32_t select_all_code_bits = 0xFFFFFFFF; // Select a 20 bit word
static const uint32_t shl_code_bits = 65536; // shift left by 10 bits
ConfigurationInterface* configuration_;
pcps_acquisition_fpga_sptr acquisition_fpga_;
uint32_t channel_;
std::weak_ptr<ChannelFsm> channel_fsm_;
uint32_t doppler_max_;
uint32_t doppler_step_;
int32_t doppler_center_;
Gnss_Synchro* gnss_synchro_;
std::string role_;
unsigned int in_streams_;

View File

@ -46,13 +46,6 @@
#include <cmath> // for abs, pow, floor
#include <complex> // for complex
#define NUM_PRNs 32
#define QUANT_BITS_LOCAL_CODE 16
#define SELECT_LSBits 0x0000FFFF // Select the 10 LSbits out of a 20-bit word
#define SELECT_MSBbits 0xFFFF0000 // Select the 10 MSbits out of a 20-bit word
#define SELECT_ALL_CODE_BITS 0xFFFFFFFF // Select a 20 bit word
#define SHL_CODE_BITS 65536 // shift left by 10 bits
GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga(
ConfigurationInterface* configuration,
const std::string& role,
@ -87,7 +80,6 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga(
// The FPGA can only use FFT lengths that are a power of two.
float nbits = ceilf(log2f((float)code_length));
unsigned int nsamples_total = pow(2, nbits);
unsigned int vector_length = nsamples_total;
unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0);
acq_parameters.select_queue_Fpga = select_queue_Fpga;
std::string default_device_name = "/dev/uio0";

View File

@ -156,6 +156,13 @@ public:
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
static const uint32_t NUM_PRNs = 32;
static const uint32_t QUANT_BITS_LOCAL_CODE = 16;
static const uint32_t SELECT_LSBits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word
static const uint32_t SELECT_MSBbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word
static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word
static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits
ConfigurationInterface* configuration_;
pcps_acquisition_fpga_sptr acquisition_fpga_;
std::string item_type_;

View File

@ -47,17 +47,6 @@
#include <cmath> // for abs, pow, floor
#include <complex> // for complex
#define NUM_PRNs 32
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
#define QUANT_BITS_LOCAL_CODE 16
#define SELECT_LSBits 0x0000FFFF // Select the 10 LSbits out of a 20-bit word
#define SELECT_MSBbits 0xFFFF0000 // Select the 10 MSbits out of a 20-bit word
#define SELECT_ALL_CODE_BITS 0xFFFFFFFF // Select a 20 bit word
#define SHL_CODE_BITS 65536 // shift left by 10 bits
GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga(
ConfigurationInterface* configuration,
const std::string& role,
@ -150,10 +139,10 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga(
// and package codes in a format that is ready to be written to the FPGA
for (uint32_t i = 0; i < nsamples_total; i++)
{
tmp = static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max));
tmp2 = static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max));
local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part
fft_data = local_code & SELECT_ALL_CODE_BITS;
tmp = static_cast<int32_t>(floor(fft_codes_padded[i].real() * (pow(2, quant_bits_local_code - 1) - 1) / max));
tmp2 = static_cast<int32_t>(floor(fft_codes_padded[i].imag() * (pow(2, quant_bits_local_code - 1) - 1) / max));
local_code = (tmp & select_lsbits) | ((tmp2 * shl_code_bits) & select_msbits); // put together the real part and the imaginary part
fft_data = local_code & select_all_code_bits;
d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data;
}
}
@ -207,6 +196,12 @@ void GpsL5iPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step)
acquisition_fpga_->set_doppler_step(doppler_step_);
}
void GpsL5iPcpsAcquisitionFpga::set_doppler_center(int doppler_center)
{
doppler_center_ = doppler_center;
acquisition_fpga_->set_doppler_center(doppler_center_);
}
void GpsL5iPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
{

View File

@ -27,7 +27,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -37,14 +37,10 @@
#include "channel_fsm.h"
#include "pcps_acquisition_fpga.h"
#include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr
#include <volk/volk_complex.h> // for lv_16sc_t
#include <cstddef> // for size_t
#include <memory>
#include <string>
#include <vector>
class Gnss_Synchro;
class ConfigurationInterface;
/*!
@ -54,13 +50,22 @@ class ConfigurationInterface;
class GpsL5iPcpsAcquisitionFpga : public AcquisitionInterface
{
public:
/*!
* \brief Constructor
*/
GpsL5iPcpsAcquisitionFpga(ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams);
/*!
* \brief Destructor
*/
~GpsL5iPcpsAcquisitionFpga() = default;
/*!
* \brief Role
*/
inline std::string role() override
{
return role_;
@ -74,14 +79,32 @@ public:
return "GPS_L5i_PCPS_Acquisition_Fpga";
}
/*!
* \brief Returns size of lv_16sc_t
*/
inline size_t item_size() override
{
return sizeof(lv_16sc_t);
return sizeof(int16_t);
}
/*!
* \brief Connect
*/
void connect(gr::top_block_sptr top_block) override;
/*!
* \brief Disconnect
*/
void disconnect(gr::top_block_sptr top_block) override;
/*!
* \brief Get left block
*/
gr::basic_block_sptr get_left_block() override;
/*!
* \brief Get right block
*/
gr::basic_block_sptr get_right_block() override;
/*!
@ -124,6 +147,11 @@ public:
*/
void set_doppler_step(unsigned int doppler_step) override;
/*!
* \brief Set Doppler center for the grid search
*/
void set_doppler_center(int doppler_center) override;
/*!
* \brief Initializes acquisition algorithm.
*/
@ -154,9 +182,22 @@ public:
*/
void stop_acquisition() override;
/*!
* \brief Set resampler latency
*/
void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{};
private:
static const uint32_t NUM_PRNs = 32;
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
static const uint32_t quant_bits_local_code = 16;
static const uint32_t select_lsbits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word
static const uint32_t select_msbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word
static const uint32_t select_all_code_bits = 0xFFFFFFFF; // Select a 20 bit word
static const uint32_t shl_code_bits = 65536; // shift left by 10 bits
ConfigurationInterface* configuration_;
pcps_acquisition_fpga_sptr acquisition_fpga_;
std::string item_type_;
@ -164,6 +205,7 @@ private:
std::weak_ptr<ChannelFsm> channel_fsm_;
uint32_t doppler_max_;
uint32_t doppler_step_;
int32_t doppler_center_;
std::string dump_filename_;
Gnss_Synchro* gnss_synchro_;
std::string role_;

View File

@ -40,8 +40,6 @@
#include <utility> // for move
#define AQ_DOWNSAMPLING_DELAY 40 // delay due to the downsampling filter in the acquisition
pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_)
{
return pcps_acquisition_fpga_sptr(new pcps_acquisition_fpga(std::move(conf_)));
@ -60,6 +58,7 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_)
d_num_doppler_bins = 0U;
d_threshold = 0.0;
d_doppler_step = 0U;
d_doppler_center = 0U;
d_doppler_index = 0U;
d_test_statistics = 0.0;
d_channel = 0U;
@ -141,7 +140,9 @@ void pcps_acquisition_fpga::send_positive_acquisition()
<< ", code phase " << d_gnss_synchro->Acq_delay_samples
<< ", doppler " << d_gnss_synchro->Acq_doppler_hz
<< ", magnitude " << d_mag
<< ", input signal power " << d_input_power;
<< ", input signal power " << d_input_power
<< ", Assist doppler_center " << d_doppler_center;
//the channel FSM is set, so, notify it directly the positive acquisition to minimize delays
d_channel_fsm.lock()->Event_valid_acquisition();
@ -211,13 +212,6 @@ void pcps_acquisition_fpga::acquisition_core(uint32_t num_doppler_bins, uint32_t
}
}
// debug
// if (d_test_statistics > d_threshold)
// {
// printf("firstpeak = %f, secondpeak = %f, test_statistics = %f reported block exp = %d PRN = %d inext = %d, initial_sample = %ld doppler = %d\n", firstpeak, secondpeak, d_test_statistics, (int)total_block_exp, (int)d_gnss_synchro->PRN, (int)indext, (long int)initial_sample, (int)doppler);
// printf("doppler_min = %d doppler_step = %d num_doppler_bins = %d\n", (int)doppler_min, (int)doppler_step, (int)num_doppler_bins);
// }
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_sample_counter = initial_sample;
@ -263,7 +257,7 @@ void pcps_acquisition_fpga::set_active(bool active)
acquisition_fpga->write_local_code();
acquisition_fpga->set_block_exp(d_total_block_exp);
acquisition_core(d_num_doppler_bins, d_doppler_step, -d_doppler_max);
acquisition_core(d_num_doppler_bins, d_doppler_step, -d_doppler_max + d_doppler_center);
if (!d_make_2_steps)
{
acquisition_fpga->close_device();
@ -290,7 +284,7 @@ void pcps_acquisition_fpga::set_active(bool active)
while (num_second_acq < d_max_num_acqs)
{
acquisition_core(d_num_doppler_bins_step2, d_doppler_step2, d_doppler_center_step_two - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0)) * d_doppler_step2);
acquisition_core(d_num_doppler_bins_step2, d_doppler_step2, d_doppler_center_step_two - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0)) * d_doppler_step2 + d_doppler_center);
if (d_test_statistics > d_threshold)
{
d_active = false;

View File

@ -44,10 +44,10 @@
#include "channel_fsm.h"
#include "fpga_acquisition.h"
#include <boost/shared_ptr.hpp>
#include <volk/volk_complex.h> // for lv_16sc_t
#include <cstdint> // for uint32_t
#include <memory> // for shared_ptr
#include <string> // for string
#include <glog/logging.h>
class Gnss_Synchro;
@ -89,6 +89,9 @@ pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_);
class pcps_acquisition_fpga
{
public:
/*!
* \brief Destructor
*/
~pcps_acquisition_fpga() = default;
/*!
@ -116,7 +119,6 @@ public:
/*!
* \brief Sets local code for PCPS acquisition algorithm.
* \param code - Pointer to the PRN code.
*/
void set_local_code();
@ -181,6 +183,19 @@ public:
acquisition_fpga->set_doppler_step(doppler_step);
}
/*!
* \brief Set Doppler center frequency for the grid search. It will refresh the Doppler grid.
* \param doppler_center - Frequency center of the search grid [Hz].
*/
inline void set_doppler_center(int32_t doppler_center)
{
if (doppler_center != d_doppler_center)
{
DLOG(INFO) << " Doppler assistance for Channel: " << d_channel << " => Doppler: " << doppler_center << "[Hz]";
d_doppler_center = doppler_center;
}
}
/*!
* \brief This function triggers a HW reset of the FPGA PL.
*/
@ -194,6 +209,7 @@ private:
uint32_t d_doppler_index;
uint32_t d_channel;
uint32_t d_doppler_step;
int32_t d_doppler_center;
uint32_t d_doppler_max;
uint32_t d_fft_size;
uint32_t d_num_doppler_bins;

View File

@ -44,22 +44,6 @@
#include <utility> // for move
// FPGA register parameters
#define PAGE_SIZE 0x10000 // default page size for the multicorrelator memory map
#define RESET_ACQUISITION 2 // command to reset the multicorrelator
#define LAUNCH_ACQUISITION 1 // command to launch the multicorrelator
#define TEST_REG_SANITY_CHECK 0x55AA // value to check the presence of the test register (to detect the hw)
#define LOCAL_CODE_CLEAR_MEM 0x10000000 // command to clear the internal memory of the multicorrelator
#define MEM_LOCAL_CODE_WR_ENABLE 0x0C000000 // command to enable the ENA and WR pins of the internal memory of the multicorrelator
#define POW_2_2 4 // 2^2 (used for the conversion of floating point numbers to integers)
#define POW_2_31 2147483648 // 2^31 (used for the conversion of floating point numbers to integers)
#define SELECT_LSBits 0x0000FFFF // Select the 10 LSbits out of a 20-bit word
#define SELECT_MSBbits 0xFFFF0000 // Select the 10 MSbits out of a 20-bit word
#define SELECT_ALL_CODE_BITS 0xFFFFFFFF // Select a 20 bit word
#define SHL_CODE_BITS 65536 // shift left by 10 bits
#ifndef TEMP_FAILURE_RETRY
#define TEMP_FAILURE_RETRY(exp) \
({ \
@ -191,12 +175,6 @@ void Fpga_Acquisition::run_acquisition(void)
std::cout << "acquisition module Read failed to retrieve 4 bytes!" << std::endl;
std::cout << "acquisition module Interrupt number " << irq_count << std::endl;
}
// nbytes = TEMP_FAILURE_RETRY(write(d_fd, reinterpret_cast<void *>(&disable_int), sizeof(int32_t)));
// if (nbytes != sizeof(int32_t))
// {
// std::cerr << "Error disabling interruptions in the FPGA." << std::endl;
// }
}
@ -229,7 +207,7 @@ void Fpga_Acquisition::set_doppler_sweep(uint32_t num_sweeps, uint32_t doppler_s
void Fpga_Acquisition::configure_acquisition()
{
//Fpga_Acquisition::open_device();
//Fpga_Acquisition::();
d_map_base[0] = d_select_queue;
d_map_base[1] = d_vector_length;
d_map_base[2] = d_nsamples;
@ -274,18 +252,6 @@ void Fpga_Acquisition::read_acquisition_results(uint32_t *max_index,
}
void Fpga_Acquisition::block_samples()
{
d_map_base[14] = 1; // block the samples
}
void Fpga_Acquisition::unblock_samples()
{
d_map_base[14] = 0; // unblock the samples
}
void Fpga_Acquisition::close_device()
{
auto *aux = const_cast<uint32_t *>(d_map_base);
@ -299,6 +265,7 @@ void Fpga_Acquisition::close_device()
void Fpga_Acquisition::reset_acquisition(void)
{
//printf("============ resetting the hw now from the acquisition ===============");
d_map_base[8] = RESET_ACQUISITION; // writing a 2 to d_map_base[8] resets the acquisition. This causes a reset of all
// the FPGA HW modules including the multicorrelators
}

View File

@ -45,6 +45,9 @@
class Fpga_Acquisition
{
public:
/*!
* \brief Constructor
*/
Fpga_Acquisition(
std::string device_name,
uint32_t nsamples,
@ -56,14 +59,29 @@ public:
uint32_t *all_fft_codes,
uint32_t excludelimit);
/*!
* \brief Destructor
*/
~Fpga_Acquisition() = default;
/*!
* \brief Select the code with the chosen PRN
*/
bool set_local_code(uint32_t PRN);
/*!
* \brief Configure the doppler sweep parameters in the FPGA
*/
void set_doppler_sweep(uint32_t num_sweeps, uint32_t doppler_step, int32_t doppler_min);
/*!
* \brief Run the acquisition process in the FPGA
*/
void run_acquisition(void);
/*!
* \brief Read the results of the acquisition process
*/
void read_acquisition_results(
uint32_t *max_index,
float *firstpeak,
@ -73,10 +91,6 @@ public:
uint32_t *doppler_index,
uint32_t *total_blk_exp);
void block_samples();
void unblock_samples();
/*!
* \brief Set maximum Doppler grid search
* \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
@ -101,21 +115,51 @@ public:
void reset_acquisition(void);
/*!
* \brief read the scaling factor that has been used by the FFT-IFFT
* \brief Read the scaling factor that has been used by the FFT-IFFT
*/
void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor);
/*!
* \brief Set the block exponent of the FFT in the FPGA.
*/
void set_block_exp(uint32_t total_block_exp);
/*!
* \brief Write the PRN code in the FPGA
*/
void write_local_code(void);
/*!
* \brief Write the acquisition parameters into the FPGA
*/
void configure_acquisition(void);
/*!
* \brief Open the device driver
*/
void open_device();
/*!
* \brief Close the device driver
*/
void close_device();
private:
// FPGA register parameters
static const uint32_t PAGE_SIZE = 0x10000; // default page size for the multicorrelator memory map
static const uint32_t RESET_ACQUISITION = 2; // command to reset the multicorrelator
static const uint32_t LAUNCH_ACQUISITION = 1; // command to launch the multicorrelator
static const uint32_t TEST_REG_SANITY_CHECK = 0x55AA; // value to check the presence of the test register (to detect the hw)
static const uint32_t LOCAL_CODE_CLEAR_MEM = 0x10000000; // command to clear the internal memory of the multicorrelator
static const uint32_t MEM_LOCAL_CODE_WR_ENABLE = 0x0C000000; // command to enable the ENA and WR pins of the internal memory of the multicorrelator
static const uint32_t POW_2_2 = 4; // 2^2 (used for the conversion of floating point numbers to integers)
static const uint32_t POW_2_31 = 2147483648; // 2^31 (used for the conversion of floating point numbers to integers)
static const uint32_t SELECT_LSBits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word
static const uint32_t SELECT_MSBbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word
static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word
static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits
int64_t d_fs_in;
// data related to the hardware module and the driver
int32_t d_fd; // driver descriptor

View File

@ -40,11 +40,6 @@
#include <iostream> // for cout, endl
#include <sys/mman.h> // for mmap
// constants
const size_t PAGE_SIZE = 0x10000;
const uint32_t TEST_REGISTER_TRACK_WRITEVAL = 0x55AA;
Fpga_Switch::Fpga_Switch(const std::string &device_name)
{
if ((d_device_descriptor = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1)

View File

@ -39,16 +39,33 @@
#include <string>
#define MAX_LENGTH_DEVICEIO_NAME 50
/*!
* \brief Class that controls the switch in the FPGA, which connects the FPGA acquisition and multicorrelator modules to
* either the DMA or the Analog Front-End.
*/
class Fpga_Switch
{
public:
/*!
* \brief Constructor
*/
Fpga_Switch(const std::string& device_name);
/*!
* \brief Destructor
*/
~Fpga_Switch();
/*!
* \brief This function configures the switch in th eFPGA
*/
void set_switch_position(int32_t switch_position);
private:
static const size_t PAGE_SIZE = 0x10000;
static const uint32_t TEST_REGISTER_TRACK_WRITEVAL = 0x55AA;
static const uint32_t MAX_LENGTH_DEVICEIO_NAME = 50;
int d_device_descriptor; // driver descriptor
volatile unsigned* d_map_base; // driver memory map

View File

@ -29,7 +29,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -41,19 +41,9 @@
#include "dll_pll_conf_fpga.h"
#include "galileo_e1_signal_processing.h"
#include "gnss_sdr_flags.h"
#include "gnss_synchro.h"
#include <glog/logging.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <array>
#include <cmath> // for round
#include <cstring> // for memcpy
#include <iostream> // for operator<<
// the following flags are FPGA-specific and they are using arrange the values of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
#define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000 // flag that enables WE (Write Enable) of the local code FPGA
#define LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT 0x20000000 // flag that selects the writing of the pilot code in the FPGA (as opposed to the data code)
GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
ConfigurationInterface* configuration, const std::string& role,
@ -82,7 +72,6 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
{
trk_param_fpga.smoother_length = configuration->property(role + ".smoother_length", 10);
}
float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 5.0);
if (FLAGS_pll_bw_hz != 0.0)
{
@ -174,31 +163,11 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
trk_param_fpga.system = 'E';
std::array<char, 3> sig_{'1', 'B', '\0'};
std::memcpy(trk_param_fpga.signal, sig_.data(), 3);
int32_t cn0_samples = configuration->property(role + ".cn0_samples", 20);
if (FLAGS_cn0_samples != 20)
{
cn0_samples = FLAGS_cn0_samples;
}
trk_param_fpga.cn0_samples = cn0_samples;
int32_t cn0_min = configuration->property(role + ".cn0_min", 25);
if (FLAGS_cn0_min != 25)
{
cn0_min = FLAGS_cn0_min;
}
trk_param_fpga.cn0_min = cn0_min;
int32_t max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
if (FLAGS_max_lock_fail != 50)
{
max_lock_fail = FLAGS_max_lock_fail;
}
trk_param_fpga.max_lock_fail = max_lock_fail;
double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85);
if (FLAGS_carrier_lock_th != 0.85)
{
carrier_lock_th = FLAGS_carrier_lock_th;
}
trk_param_fpga.carrier_lock_th = carrier_lock_th;
trk_param_fpga.cn0_samples = configuration->property(role + ".cn0_samples", trk_param_fpga.cn0_samples);
trk_param_fpga.cn0_min = configuration->property(role + ".cn0_min", trk_param_fpga.cn0_min);
trk_param_fpga.max_code_lock_fail = configuration->property(role + ".max_lock_fail", trk_param_fpga.max_code_lock_fail);
trk_param_fpga.max_carrier_lock_fail = configuration->property(role + ".max_carrier_lock_fail", trk_param_fpga.max_carrier_lock_fail);
trk_param_fpga.carrier_lock_th = configuration->property(role + ".carrier_lock_th", trk_param_fpga.carrier_lock_th);
// FPGA configuration parameters
std::string default_device_name = "/dev/uio";
@ -206,7 +175,6 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
trk_param_fpga.device_name = device_name;
uint32_t device_base = configuration->property(role + ".device_base", 15);
trk_param_fpga.device_base = device_base;
trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> 5 correlators
//################# PRE-COMPUTE ALL THE CODES #################
uint32_t code_samples_per_chip = 2;
@ -281,6 +249,9 @@ GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga(
trk_param_fpga.data_codes = d_data_codes;
trk_param_fpga.code_length_chips = GALILEO_E1_B_CODE_LENGTH_CHIPS;
trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip
trk_param_fpga.extended_correlation_in_fpga = false;
trk_param_fpga.extend_fpga_integration_periods = 1; // (number of FPGA integrations that are combined in the SW)
trk_param_fpga.fpga_integration_period = 1; // (number of symbols that are effectively integrated in the FPGA)
//################# MAKE TRACKING GNURadio object ###################
tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga);
channel_ = 0;

View File

@ -29,7 +29,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -39,12 +39,9 @@
#include "dll_pll_veml_tracking_fpga.h"
#include "tracking_interface.h"
#include <gnuradio/runtime_types.h> // for basic_block_sptr, basic_block_sptr
#include <cstddef> // for size_t
#include <cstdint> // for uint32_t
#include <string> // for string
#include <string>
class Gnss_Synchro;
class ConfigurationInterface;
/*!
@ -54,32 +51,61 @@ class ConfigurationInterface;
class GalileoE1DllPllVemlTrackingFpga : public TrackingInterface
{
public:
/*!
* \brief Constructor
*/
GalileoE1DllPllVemlTrackingFpga(ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams);
/*!
* \brief Destructor
*/
virtual ~GalileoE1DllPllVemlTrackingFpga();
/*!
* \brief Role
*/
inline std::string role() override
{
return role_;
}
//! Returns "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"
/*!
* \brief Returns "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"
*/
inline std::string implementation() override
{
return "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga";
}
inline size_t item_size() override
/*!
* \brief Returns size of lv_16sc_t
*/
size_t item_size() override
{
return sizeof(int);
return sizeof(int16_t);
}
/*!
* \brief Connect
*/
void connect(gr::top_block_sptr top_block) override;
/*!
* \brief Disconnect
*/
void disconnect(gr::top_block_sptr top_block) override;
/*!
* \brief Get left block
*/
gr::basic_block_sptr get_left_block() override;
/*!
* \brief Get right block
*/
gr::basic_block_sptr get_right_block() override;
/*!
@ -94,14 +120,22 @@ public:
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
/*!
* \brief Start the tracking process in the FPGA
*/
void start_tracking() override;
/*!
* \brief Stop running tracking
* \brief Stop the tracking process in the FPGA
*/
void stop_tracking() override;
private:
// the following flags are FPGA-specific and they are using arrange the values of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
static const int32_t LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY = 0x0C000000; // flag that enables WE (Write Enable) of the local code FPGA
static const int32_t LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT = 0x20000000; // flag that selects the writing of the pilot code in the FPGA (as opposed to the data code)
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
uint32_t channel_;
std::string role_;

View File

@ -24,7 +24,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -36,21 +36,9 @@
#include "dll_pll_conf_fpga.h"
#include "galileo_e5_signal_processing.h"
#include "gnss_sdr_flags.h"
#include "gnss_synchro.h"
#include <glog/logging.h>
#include <gnuradio/gr_complex.h> // for gr_complex
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <array>
#include <cmath> // for round
#include <complex>
#include <cstring> // for memcpy
#include <iostream>
// the following flags are FPGA-specific and they are using arrange the values of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
#define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000 // flag that enables WE (Write Enable) of the local code FPGA
#define LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT 0x20000000 // flag that selects the writing of the pilot code in the FPGA (as opposed to the data code)
GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga(
ConfigurationInterface *configuration, const std::string &role,
@ -168,30 +156,11 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga(
trk_param_fpga.system = 'E';
std::array<char, 3> sig_{'5', 'X', '\0'};
std::memcpy(trk_param_fpga.signal, sig_.data(), 3);
int32_t cn0_samples = configuration->property(role + ".cn0_samples", 20);
if (FLAGS_cn0_samples != 20)
{
cn0_samples = FLAGS_cn0_samples;
}
trk_param_fpga.cn0_samples = cn0_samples;
int32_t cn0_min = configuration->property(role + ".cn0_min", 25);
if (FLAGS_cn0_min != 25)
{
cn0_min = FLAGS_cn0_min;
}
trk_param_fpga.cn0_min = cn0_min;
int32_t max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
if (FLAGS_max_lock_fail != 50)
{
max_lock_fail = FLAGS_max_lock_fail;
}
trk_param_fpga.max_lock_fail = max_lock_fail;
double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85);
if (FLAGS_carrier_lock_th != 0.85)
{
carrier_lock_th = FLAGS_carrier_lock_th;
}
trk_param_fpga.carrier_lock_th = carrier_lock_th;
trk_param_fpga.cn0_samples = configuration->property(role + ".cn0_samples", trk_param_fpga.cn0_samples);
trk_param_fpga.cn0_min = configuration->property(role + ".cn0_min", trk_param_fpga.cn0_min);
trk_param_fpga.max_code_lock_fail = configuration->property(role + ".max_lock_fail", trk_param_fpga.max_code_lock_fail);
trk_param_fpga.max_carrier_lock_fail = configuration->property(role + ".max_carrier_lock_fail", trk_param_fpga.max_carrier_lock_fail);
trk_param_fpga.carrier_lock_th = configuration->property(role + ".carrier_lock_th", trk_param_fpga.carrier_lock_th);
d_data_codes = nullptr;
@ -201,7 +170,6 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga(
trk_param_fpga.device_name = device_name;
uint32_t device_base = configuration->property(role + ".device_base", 27);
trk_param_fpga.device_base = device_base;
trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> up to 5+1 correlators
//################# PRE-COMPUTE ALL THE CODES #################
uint32_t code_samples_per_chip = 1;
@ -264,6 +232,34 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga(
trk_param_fpga.data_codes = d_data_codes;
trk_param_fpga.code_length_chips = code_length_chips;
trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip
trk_param_fpga.extended_correlation_in_fpga = false; // by default
trk_param_fpga.extend_fpga_integration_periods = 1; // (number of FPGA integrations that are combined in the SW)
trk_param_fpga.fpga_integration_period = 1; // (number of symbols that are effectively integrated in the FPGA)
if (d_track_pilot)
{
if (extend_correlation_symbols > 1)
{
if (extend_correlation_symbols <= GALILEO_E5A_I_SECONDARY_CODE_LENGTH)
{
if ((GALILEO_E5A_I_SECONDARY_CODE_LENGTH % extend_correlation_symbols) == 0)
{
trk_param_fpga.extended_correlation_in_fpga = true;
trk_param_fpga.fpga_integration_period = extend_correlation_symbols;
}
}
else
{
if (extend_correlation_symbols % GALILEO_E5A_I_SECONDARY_CODE_LENGTH == 0)
{
trk_param_fpga.extended_correlation_in_fpga = true;
trk_param_fpga.extend_fpga_integration_periods = extend_correlation_symbols / GALILEO_E5A_I_SECONDARY_CODE_LENGTH;
trk_param_fpga.fpga_integration_period = GALILEO_E5A_I_SECONDARY_CODE_LENGTH;
}
}
}
}
//################# MAKE TRACKING GNURadio object ###################
tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga);
channel_ = 0;

View File

@ -24,7 +24,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -34,12 +34,8 @@
#include "dll_pll_veml_tracking_fpga.h"
#include "tracking_interface.h"
#include <gnuradio/runtime_types.h> // for basic_block_sptr
#include <cstdint> // For uint32_t
#include <stddef.h> // for size_t
#include <string>
class Gnss_Synchro;
class ConfigurationInterface;
/*!
@ -48,32 +44,61 @@ class ConfigurationInterface;
class GalileoE5aDllPllTrackingFpga : public TrackingInterface
{
public:
/*!
* \brief Constructor
*/
GalileoE5aDllPllTrackingFpga(ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams);
/*!
* \brief Destructor
*/
virtual ~GalileoE5aDllPllTrackingFpga();
/*!
* \brief Role
*/
inline std::string role() override
{
return role_;
}
//! Returns "Galileo_E5a_DLL_PLL_Tracking_Fpga"
/*!
* \brief Returns "Galileo_E5a_DLL_PLL_Tracking_Fpga"
*/
inline std::string implementation() override
{
return "Galileo_E5a_DLL_PLL_Tracking_Fpga";
}
inline size_t item_size() override
/*!
* \brief Returns size of lv_16sc_t
*/
size_t item_size() override
{
return sizeof(int);
return sizeof(int16_t);
}
/*!
* \brief Connect
*/
void connect(gr::top_block_sptr top_block) override;
/*!
* \brief Disconnect
*/
void disconnect(gr::top_block_sptr top_block) override;
/*!
* \brief Get left block
*/
gr::basic_block_sptr get_left_block() override;
/*!
* \brief Get right block
*/
gr::basic_block_sptr get_right_block() override;
/*!
@ -87,13 +112,23 @@ public:
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
void start_tracking() override;
/*!
* \brief Stop running tracking
* \brief Start the tracking process in the FPGA
*/
void start_tracking() override;
/*!
* \brief Stop the tracking process in the FPGA
*/
void stop_tracking() override;
private:
// the following flags are FPGA-specific and they are using arrange the values of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
static const int32_t LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY = 0x0C000000; // flag that enables WE (Write Enable) of the local code FPGA
static const int32_t LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT = 0x20000000; // flag that selects the writing of the pilot code in the FPGA (as opposed to the data code)
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
uint32_t channel_;
std::string role_;

View File

@ -29,7 +29,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -40,20 +40,10 @@
#include "display.h"
#include "dll_pll_conf_fpga.h"
#include "gnss_sdr_flags.h"
#include "gnss_synchro.h"
#include "gps_sdr_signal_processing.h"
#include <glog/logging.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <array>
#include <cmath> // for round
#include <cstring> // for memcpy
#include <iostream>
#define NUM_PRNs 32 // total number of PRNs
// the following flag is FPGA-specific and they are using arrange the values of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
#define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000 // flag that enables WE (Write Enable) of the local code FPGA
GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
ConfigurationInterface* configuration, const std::string& role,
@ -61,7 +51,6 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
{
Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga();
DLOG(INFO) << "role " << role;
//################# CONFIGURATION PARAMETERS ########################
int32_t fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
int32_t fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
@ -76,7 +65,6 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
{
trk_param_fpga.smoother_length = configuration->property(role + ".smoother_length", 10);
}
bool dump = configuration->property(role + ".dump", false);
trk_param_fpga.dump = dump;
std::string default_dump_filename = "./track_ch";
@ -155,9 +143,9 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
symbols_extended_correlator = 1;
std::cout << TEXT_RED << "WARNING: GPS L1 C/A. extend_correlation_symbols must be bigger than 1. Coherent integration has been set to 1 symbol (1 ms)" << TEXT_RESET << std::endl;
}
else if (symbols_extended_correlator > 20)
else if (symbols_extended_correlator > GPS_CA_BIT_DURATION_MS)
{
symbols_extended_correlator = 20;
symbols_extended_correlator = GPS_CA_BIT_DURATION_MS;
std::cout << TEXT_RED << "WARNING: GPS L1 C/A. extend_correlation_symbols must be lower than 21. Coherent integration has been set to 20 symbols (20 ms)" << TEXT_RESET << std::endl;
}
trk_param_fpga.extend_correlation_symbols = symbols_extended_correlator;
@ -176,30 +164,11 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
trk_param_fpga.system = 'G';
std::array<char, 3> sig_{'1', 'C', '\0'};
std::memcpy(trk_param_fpga.signal, sig_.data(), 3);
int32_t cn0_samples = configuration->property(role + ".cn0_samples", 20);
if (FLAGS_cn0_samples != 20)
{
cn0_samples = FLAGS_cn0_samples;
}
trk_param_fpga.cn0_samples = cn0_samples;
int32_t cn0_min = configuration->property(role + ".cn0_min", 30);
if (FLAGS_cn0_min != 25)
{
cn0_min = FLAGS_cn0_min;
}
trk_param_fpga.cn0_min = cn0_min;
int32_t max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
if (FLAGS_max_lock_fail != 50)
{
max_lock_fail = FLAGS_max_lock_fail;
}
trk_param_fpga.max_lock_fail = max_lock_fail;
double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.80);
if (FLAGS_carrier_lock_th != 0.85)
{
carrier_lock_th = FLAGS_carrier_lock_th;
}
trk_param_fpga.carrier_lock_th = carrier_lock_th;
trk_param_fpga.cn0_samples = configuration->property(role + ".cn0_samples", trk_param_fpga.cn0_samples);
trk_param_fpga.cn0_min = configuration->property(role + ".cn0_min", trk_param_fpga.cn0_min);
trk_param_fpga.max_code_lock_fail = configuration->property(role + ".max_lock_fail", trk_param_fpga.max_code_lock_fail);
trk_param_fpga.max_carrier_lock_fail = configuration->property(role + ".max_carrier_lock_fail", trk_param_fpga.max_carrier_lock_fail);
trk_param_fpga.carrier_lock_th = configuration->property(role + ".carrier_lock_th", trk_param_fpga.carrier_lock_th);
// FPGA configuration parameters
std::string default_device_name = "/dev/uio";
@ -207,7 +176,6 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
trk_param_fpga.device_name = device_name;
uint32_t device_base = configuration->property(role + ".device_base", 3);
trk_param_fpga.device_base = device_base;
trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators
//################# PRE-COMPUTE ALL THE CODES #################
d_ca_codes = static_cast<int32_t*>(volk_gnsssdr_malloc(static_cast<int32_t>(GPS_L1_CA_CODE_LENGTH_CHIPS * NUM_PRNs) * sizeof(int32_t), volk_gnsssdr_get_alignment()));
@ -231,6 +199,22 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga(
trk_param_fpga.code_length_chips = GPS_L1_CA_CODE_LENGTH_CHIPS;
trk_param_fpga.code_samples_per_chip = 1; // 1 sample per chip
trk_param_fpga.extended_correlation_in_fpga = false; // by default
trk_param_fpga.extend_fpga_integration_periods = 1; // (number of FPGA integrations that are combined in the SW)
trk_param_fpga.fpga_integration_period = 1; // (number of symbols that are effectively integrated in the FPGA)
if (symbols_extended_correlator > 1)
{
if (symbols_extended_correlator <= GPS_CA_BIT_DURATION_MS)
{
if ((GPS_CA_BIT_DURATION_MS % symbols_extended_correlator) == 0)
{
trk_param_fpga.extended_correlation_in_fpga = true;
trk_param_fpga.fpga_integration_period = symbols_extended_correlator;
}
}
}
//################# MAKE TRACKING GNURadio object ###################
tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga);
channel_ = 0;

View File

@ -29,7 +29,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -39,12 +39,8 @@
#include "dll_pll_veml_tracking_fpga.h"
#include "tracking_interface.h"
#include <gnuradio/runtime_types.h>
#include <cstddef>
#include <string>
class Gnss_Synchro;
class ConfigurationInterface;
/*!
@ -53,32 +49,61 @@ class ConfigurationInterface;
class GpsL1CaDllPllTrackingFpga : public TrackingInterface
{
public:
/*!
* \brief Constructor
*/
GpsL1CaDllPllTrackingFpga(ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams);
/*!
* \brief Destructor
*/
virtual ~GpsL1CaDllPllTrackingFpga();
/*!
* \brief Role
*/
inline std::string role() override
{
return role_;
}
//! Returns "GPS_L1_CA_DLL_PLL_Tracking_Fpga"
/*!
* \brief Returns "GPS_L1_CA_DLL_PLL_Tracking_Fpga"
*/
inline std::string implementation() override
{
return "GPS_L1_CA_DLL_PLL_Tracking_Fpga";
}
inline size_t item_size() override
/*!
* \brief Returns size of lv_16sc_t
*/
size_t item_size() override
{
return sizeof(int);
return sizeof(int16_t);
}
/*!
* \brief Connect
*/
void connect(gr::top_block_sptr top_block) override;
/*!
* \brief Disconnect
*/
void disconnect(gr::top_block_sptr top_block) override;
/*!
* \brief Get left block
*/
gr::basic_block_sptr get_left_block() override;
/*!
* \brief Get right block
*/
gr::basic_block_sptr get_right_block() override;
/*!
@ -92,14 +117,24 @@ public:
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
/*!
* \brief Start the tracking process in the FPGA
*/
void start_tracking() override;
/*!
* \brief Stop running tracking
* \brief Stop the tracking process in the FPGA
*/
void stop_tracking() override;
private:
static const uint32_t NUM_PRNs = 32; // total number of PRNs
static const int32_t GPS_CA_BIT_DURATION_MS = 20;
// the following flag is FPGA-specific and they are using arrange the values of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
static const int32_t LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY = 0x0C000000; // flag that enables WE (Write Enable) of the local code FPGA
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
uint32_t channel_;
std::string role_;

View File

@ -50,9 +50,6 @@
#include <cstring> // for memcpy
#include <iostream>
#define NUM_PRNs 32
GpsL2MDllPllTrackingFpga::GpsL2MDllPllTrackingFpga(
ConfigurationInterface* configuration, const std::string& role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)
@ -100,18 +97,18 @@ GpsL2MDllPllTrackingFpga::GpsL2MDllPllTrackingFpga(
trk_param_fpga.system = 'G';
std::array<char, 3> sig_{'2', 'S', '\0'};
std::memcpy(trk_param_fpga.signal, sig_.data(), 3);
int cn0_samples = configuration->property(role + ".cn0_samples", 20);
if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples;
trk_param_fpga.cn0_samples = cn0_samples;
int cn0_min = configuration->property(role + ".cn0_min", 25);
if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min;
trk_param_fpga.cn0_min = cn0_min;
int max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail;
trk_param_fpga.max_lock_fail = max_lock_fail;
double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85);
if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th;
trk_param_fpga.carrier_lock_th = carrier_lock_th;
trk_param_fpga.cn0_samples = configuration->property(role + ".cn0_samples", trk_param_fpga.cn0_samples);
trk_param_fpga.cn0_min = configuration->property(role + ".cn0_min", trk_param_fpga.cn0_min);
trk_param_fpga.max_code_lock_fail = configuration->property(role + ".max_lock_fail", trk_param_fpga.max_code_lock_fail);
trk_param_fpga.max_carrier_lock_fail = configuration->property(role + ".max_carrier_lock_fail", trk_param_fpga.max_carrier_lock_fail);
trk_param_fpga.carrier_lock_th = configuration->property(role + ".carrier_lock_th", trk_param_fpga.carrier_lock_th);
// int32_t max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
// if (FLAGS_max_lock_fail != 50)
// {
// max_lock_fail = FLAGS_max_lock_fail;
// }
// trk_param_fpga.max_lock_fail = max_lock_fail;
// FPGA configuration parameters
std::string default_device_name = "/dev/uio";
@ -119,14 +116,12 @@ GpsL2MDllPllTrackingFpga::GpsL2MDllPllTrackingFpga(
trk_param_fpga.device_name = device_name;
unsigned int device_base = configuration->property(role + ".device_base", 1);
trk_param_fpga.device_base = device_base;
//unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0);
trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators
auto* ca_codes_f = static_cast<float*>(volk_gnsssdr_malloc(static_cast<unsigned int>(GPS_L2_M_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment()));
//################# PRE-COMPUTE ALL THE CODES #################
d_ca_codes = static_cast<int*>(volk_gnsssdr_malloc(static_cast<int>(GPS_L2_M_CODE_LENGTH_CHIPS * NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment()));
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++)
{
gps_l2c_m_code_gen_float(gsl::span<float>(ca_codes_f, static_cast<unsigned int>(GPS_L2_M_CODE_LENGTH_CHIPS)), PRN);
for (unsigned int s = 0; s < 2 * static_cast<unsigned int>(GPS_L2_M_CODE_LENGTH_CHIPS); s++)

View File

@ -99,6 +99,7 @@ public:
void stop_tracking() override;
private:
static const uint32_t NUM_PRNs = 32;
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
unsigned int channel_;
std::string role_;

View File

@ -30,7 +30,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -42,22 +42,10 @@
#include "display.h"
#include "dll_pll_conf_fpga.h"
#include "gnss_sdr_flags.h"
#include "gnss_synchro.h"
#include "gps_l5_signal.h"
#include <glog/logging.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <array>
#include <cmath> // for round
#include <cstring> // for memcpy
#include <iostream>
#define NUM_PRNs 32 // number of PRNS
// the following flags are FPGA-specific and they are using arrange the values of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
#define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000 // flag that enables WE (Write Enable) of the local code FPGA
#define LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT 0x20000000 // flag that selects the writing of the pilot code in the FPGA (as opposed to the data code)
GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga(
ConfigurationInterface *configuration, const std::string &role,
@ -175,30 +163,11 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga(
trk_param_fpga.system = 'G';
std::array<char, 3> sig_{'L', '5', '\0'};
std::memcpy(trk_param_fpga.signal, sig_.data(), 3);
int32_t cn0_samples = configuration->property(role + ".cn0_samples", 20);
if (FLAGS_cn0_samples != 20)
{
cn0_samples = FLAGS_cn0_samples;
}
trk_param_fpga.cn0_samples = cn0_samples;
int32_t cn0_min = configuration->property(role + ".cn0_min", 25);
if (FLAGS_cn0_min != 25)
{
cn0_min = FLAGS_cn0_min;
}
trk_param_fpga.cn0_min = cn0_min;
int32_t max_lock_fail = configuration->property(role + ".max_lock_fail", 50);
if (FLAGS_max_lock_fail != 50)
{
max_lock_fail = FLAGS_max_lock_fail;
}
trk_param_fpga.max_lock_fail = max_lock_fail;
double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.75);
if (FLAGS_carrier_lock_th != 0.85)
{
carrier_lock_th = FLAGS_carrier_lock_th;
}
trk_param_fpga.carrier_lock_th = carrier_lock_th;
trk_param_fpga.cn0_samples = configuration->property(role + ".cn0_samples", trk_param_fpga.cn0_samples);
trk_param_fpga.cn0_min = configuration->property(role + ".cn0_min", trk_param_fpga.cn0_min);
trk_param_fpga.max_code_lock_fail = configuration->property(role + ".max_lock_fail", trk_param_fpga.max_code_lock_fail);
trk_param_fpga.max_carrier_lock_fail = configuration->property(role + ".max_carrier_lock_fail", trk_param_fpga.max_carrier_lock_fail);
trk_param_fpga.carrier_lock_th = configuration->property(role + ".carrier_lock_th", trk_param_fpga.carrier_lock_th);
// FPGA configuration parameters
std::string default_device_name = "/dev/uio";
@ -206,7 +175,6 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga(
trk_param_fpga.device_name = device_name;
uint32_t device_base = configuration->property(role + ".device_base", 27);
trk_param_fpga.device_base = device_base;
trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators
//################# PRE-COMPUTE ALL THE CODES #################
uint32_t code_samples_per_chip = 1;
auto code_length_chips = static_cast<uint32_t>(GPS_L5I_CODE_LENGTH_CHIPS);
@ -287,6 +255,34 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga(
trk_param_fpga.data_codes = d_data_codes;
trk_param_fpga.code_length_chips = code_length_chips;
trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip
trk_param_fpga.extended_correlation_in_fpga = false; // by default
trk_param_fpga.extend_fpga_integration_periods = 1; // (number of FPGA integrations that are combined in the SW)
trk_param_fpga.fpga_integration_period = 1; // (number of symbols that are effectively integrated in the FPGA)
if (d_track_pilot)
{
if (extend_correlation_symbols > 1)
{
if (extend_correlation_symbols <= GPS_L5I_NH_CODE_LENGTH)
{
if ((GPS_L5I_NH_CODE_LENGTH % extend_correlation_symbols) == 0)
{
trk_param_fpga.extended_correlation_in_fpga = true;
trk_param_fpga.fpga_integration_period = extend_correlation_symbols;
}
}
else
{
if (extend_correlation_symbols % GPS_L5I_NH_CODE_LENGTH == 0)
{
trk_param_fpga.extended_correlation_in_fpga = true;
trk_param_fpga.extend_fpga_integration_periods = extend_correlation_symbols / GPS_L5I_NH_CODE_LENGTH;
trk_param_fpga.fpga_integration_period = GPS_L5I_NH_CODE_LENGTH;
}
}
}
}
tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga);
channel_ = 0;
DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")";

View File

@ -30,7 +30,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -40,12 +40,8 @@
#include "dll_pll_veml_tracking_fpga.h"
#include "tracking_interface.h"
#include <gnuradio/runtime_types.h>
#include <cstddef>
#include <cstdint>
#include <string>
class Gnss_Synchro;
class ConfigurationInterface;
/*!
@ -54,32 +50,61 @@ class ConfigurationInterface;
class GpsL5DllPllTrackingFpga : public TrackingInterface
{
public:
/*!
* \brief Constructor
*/
GpsL5DllPllTrackingFpga(ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_streams,
unsigned int out_streams);
/*!
* \brief Destructor
*/
virtual ~GpsL5DllPllTrackingFpga();
/*!
* \brief Role
*/
inline std::string role() override
{
return role_;
}
//! Returns "GPS_L5_DLL_PLL_Tracking_Fpga"
/*!
* \brief Returns "GPS_L5_DLL_PLL_Tracking_Fpga"
*/
inline std::string implementation() override
{
return "GPS_L5_DLL_PLL_Tracking_Fpga";
}
inline size_t item_size() override
/*!
* \brief Returns size of lv_16sc_t
*/
size_t item_size() override
{
return sizeof(int);
return sizeof(int16_t);
}
/*!
* \brief Connect
*/
void connect(gr::top_block_sptr top_block) override;
/*!
* \brief Disconnect
*/
void disconnect(gr::top_block_sptr top_block) override;
/*!
* \brief Get left block
*/
gr::basic_block_sptr get_left_block() override;
/*!
* \brief Get right block
*/
gr::basic_block_sptr get_right_block() override;
/*!
@ -93,14 +118,24 @@ public:
*/
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
/*!
* \brief Start the tracking process in the FPGA
*/
void start_tracking() override;
/*!
* \brief Stop running tracking
* \brief Stop the tracking process in the FPGA
*/
void stop_tracking() override;
private:
static const uint32_t NUM_PRNs = 32; // total number of PRNs
// the following flags are FPGA-specific and they are using arrange the values of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
static const int32_t LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY = 0x0C000000; // flag that enables WE (Write Enable) of the local code FPGA
static const int32_t LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT = 0x20000000; // flag that selects the writing of the pilot code in the FPGA (as opposed to the data code)
dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc;
uint32_t channel_;
std::string role_;

View File

@ -43,11 +43,8 @@
#include <gnuradio/types.h> // for gr_vector_int, gr_vector...
#include <pmt/pmt.h> // for pmt_t
#include <cstdint> // for int32_t
#include <deque> // for deque
#include <fstream> // for string, ofstream
#include <memory> // for shared_ptr
#include <string>
#include <utility> // for pair
#include <utility> // for pair
#include <vector>
class Fpga_Multicorrelator_8sc;
@ -65,23 +62,51 @@ dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Co
class dll_pll_veml_tracking_fpga : public gr::block
{
public:
/*!
* \brief Destructor
*/
~dll_pll_veml_tracking_fpga();
/*!
* \brief Set the channel number and configure some multicorrelator parameters
*/
void set_channel(uint32_t channel);
/*!
* \brief This function is used with two purposes:
* 1 -> To set the gnss_synchro
* 2 -> A set_gnss_synchro command with a valid PRN is received when the system is going to run
* acquisition with that PRN. We can use this command to pre-initialize tracking parameters and
* variables before the actual acquisition process takes place. In this way we minimize the
* latency between acquisition and tracking once the acquisition has been made.
*/
void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro);
/*!
* \brief This function starts the tracking process
*/
void start_tracking();
/*!
* \brief This function sets a flag that makes general_work to stop in order to finish the tracking process.
*/
void stop_tracking();
/*!
* \brief General Work
*/
int general_work(int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
/*!
* \brief This function disables the HW multicorrelator in the FPGA in order to stop the tracking process
*/
void reset(void);
private:
friend dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_);
void msg_handler_telemetry_to_trk(const pmt::pmt_t &msg);
dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_);
void msg_handler_preamble_index(pmt::pmt_t msg);
bool cn0_and_tracking_lock_status(double coh_integration_time_s);
bool acquire_secondary();
@ -90,11 +115,9 @@ private:
void update_tracking_vars();
void clear_tracking_vars();
void save_correlation_results();
void log_data(bool integrating);
void log_data();
int32_t save_matfile();
//void run_state_2(Gnss_Synchro &current_synchro_data);
// tracking configuration vars
Dll_Pll_Conf_Fpga trk_parameters;
bool d_veml;
@ -102,25 +125,25 @@ private:
uint32_t d_channel;
Gnss_Synchro *d_acquisition_gnss_synchro;
//Signal parameters
// Signal parameters
bool d_secondary;
bool interchange_iq;
double d_signal_carrier_freq;
double d_code_period;
double d_code_chip_rate;
uint32_t d_secondary_code_length;
uint32_t d_data_secondary_code_length;
uint32_t d_code_length_chips;
uint32_t d_code_samples_per_chip; // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled)
int32_t d_symbols_per_bit;
std::string systemName;
std::string signal_type;
std::string *d_secondary_code_string;
std::string *d_data_secondary_code_string;
std::string signal_pretty_name;
int32_t *d_preambles_symbols;
int32_t d_preamble_length_symbols;
boost::circular_buffer<float> d_symbol_history;
// dll filter buffer
boost::circular_buffer<float> d_dll_filt_history;
// tracking state machine
int32_t d_state;
@ -141,6 +164,7 @@ private:
bool d_enable_extended_integration;
int32_t d_extend_correlation_symbols_count;
int32_t d_current_symbol;
int32_t d_current_data_symbol;
gr_complex d_VE_accu;
gr_complex d_E_accu;
@ -149,6 +173,7 @@ private:
gr_complex d_L_accu;
gr_complex d_VL_accu;
gr_complex d_P_data_accu;
gr_complex *d_Prompt_Data;
double d_code_phase_step_chips;
@ -157,11 +182,12 @@ private:
double d_carrier_phase_step_rad;
double d_carrier_phase_rate_step_rad;
boost::circular_buffer<std::pair<double, double>> d_carr_ph_history;
// remaining code phase and carrier phase between tracking loops
double d_rem_code_phase_samples;
double d_rem_code_phase_samples_prev;
float d_rem_carr_phase_rad;
// PLL and DLL filter library
Tracking_loop_filter d_code_loop_filter;
Tracking_FLL_PLL_filter d_carrier_loop_filter;
@ -171,6 +197,7 @@ private:
// tracking vars
bool d_pull_in_transitory;
bool d_corrected_doppler;
double d_current_correlation_time_s;
double d_carr_phase_error_hz;
double d_carr_freq_error_hz;
@ -185,36 +212,44 @@ private:
double T_prn_seconds;
double T_prn_samples;
double K_blk_samples;
// PRN period in samples
int32_t d_current_prn_length_samples;
// integration period in samples
int32_t d_current_integration_length_samples;
// processing samples counters
uint64_t d_sample_counter;
uint64_t d_acq_sample_stamp;
uint64_t d_absolute_samples_offset;
// CN0 estimation and lock detector
int32_t d_cn0_estimation_counter;
int32_t d_carrier_lock_fail_counter;
//std::deque<float> d_carrier_lock_detector_queue;
int32_t d_code_lock_fail_counter;
double d_carrier_lock_test;
double d_CN0_SNV_dB_Hz;
double d_carrier_lock_threshold;
boost::circular_buffer<gr_complex> d_Prompt_circular_buffer;
//std::deque<gr_complex> d_Prompt_buffer_deque;
std::vector<gr_complex> d_Prompt_buffer;
Exponential_Smoother d_cn0_smoother;
Exponential_Smoother d_carrier_lock_test_smoother;
// file dump
std::ofstream d_dump_file;
std::string d_dump_filename;
bool d_dump;
bool d_dump_mat;
// extra
int32_t d_correlation_length_samples;
int32_t d_next_prn_length_samples;
bool d_extended_correlation_in_fpga;
bool d_current_extended_correlation_in_fpga;
int32_t d_next_integration_length_samples;
double d_extended_integration_first_acc_carrier_phase_rad;
double d_extended_integration_next_acc_carrier_phase_rad_step;
uint64_t d_sample_counter_next;
bool d_sc_demodulate_enabled;
int32_t d_extend_fpga_integration_periods;
uint32_t d_fpga_integration_period;
uint32_t d_current_fpga_integration_period;
bool d_worker_is_done;
boost::condition_variable m_condition;
boost::mutex d_mutex;
bool d_stop_tracking;
};
#endif //GNSS_SDR_DLL_PLL_VEML_TRACKING_FPGA_H

View File

@ -32,6 +32,8 @@
#include "dll_pll_conf_fpga.h"
#include "gnss_sdr_flags.h"
#include <cstring>
Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga()
{
@ -45,7 +47,8 @@ Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga()
dump_filename = std::string("./dll_pll_dump.dat");
enable_fll_pull_in = false;
enable_fll_steady_state = false;
pull_in_time_s = 2;
pull_in_time_s = 10;
bit_synchronization_time_limit_s = pull_in_time_s + 60;
fll_filter_order = 1;
pll_filter_order = 3;
dll_filter_order = 2;
@ -61,10 +64,13 @@ Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga()
early_late_space_narrow_chips = 0.1;
very_early_late_space_narrow_chips = 0.1;
extend_correlation_symbols = 5;
cn0_samples = 20;
cn0_min = 25;
max_lock_fail = 50;
carrier_lock_th = 0.85;
cn0_samples = FLAGS_cn0_samples;
cn0_min = FLAGS_cn0_min;
max_carrier_lock_fail = FLAGS_max_carrier_lock_fail;
max_code_lock_fail = FLAGS_max_lock_fail;
carrier_lock_th = FLAGS_carrier_lock_th;
//max_lock_fail = 50;
enable_doppler_correction = false;
track_pilot = false;
system = 'G';
signal[0] = '1';
@ -72,9 +78,11 @@ Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga()
signal[2] = '\0';
device_name = "/dev/uio";
device_base = 1U;
multicorr_type = 0U;
code_length_chips = 0U;
code_samples_per_chip = 0U;
ca_codes = nullptr;
data_codes = nullptr;
extended_correlation_in_fpga = false;
extend_fpga_integration_periods = 1;
fpga_integration_period = 0;
}

View File

@ -42,14 +42,15 @@ class Dll_Pll_Conf_Fpga
{
public:
/* DLL/PLL tracking configuration */
int fll_filter_order;
bool enable_fll_pull_in;
bool enable_fll_steady_state;
unsigned int pull_in_time_s; // signed integer, when pull in time is not yet reached it has to be compared against a negative number
unsigned int bit_synchronization_time_limit_s;
int pll_filter_order;
int dll_filter_order;
double fs_in;
uint32_t vector_length;
bool dump;
@ -70,19 +71,24 @@ public:
bool high_dyn;
int32_t cn0_samples;
int32_t cn0_min;
int32_t max_lock_fail;
int32_t max_code_lock_fail;
int32_t max_carrier_lock_fail;
//int32_t max_lock_fail;
uint32_t smoother_length;
double carrier_lock_th;
bool track_pilot;
bool enable_doppler_correction;
char system;
char signal[3];
std::string device_name;
uint32_t device_base;
uint32_t multicorr_type;
uint32_t code_length_chips;
uint32_t code_samples_per_chip;
int32_t* ca_codes;
int32_t* data_codes;
bool extended_correlation_in_fpga;
uint32_t extend_fpga_integration_periods;
uint32_t fpga_integration_period;
Dll_Pll_Conf_Fpga();
};

View File

@ -43,20 +43,6 @@
#include <sys/mman.h> // for PROT_READ, PROT_WRITE, MAP_SHARED
#include <utility>
// FPGA register access constants
#define PAGE_SIZE 0x10000
#define MAX_LENGTH_DEVICEIO_NAME 50
#define CODE_RESAMPLER_NUM_BITS_PRECISION 20
#define CODE_PHASE_STEP_CHIPS_NUM_NBITS CODE_RESAMPLER_NUM_BITS_PRECISION
#define pwrtwo(x) (1 << (x))
#define MAX_CODE_RESAMPLER_COUNTER pwrtwo(CODE_PHASE_STEP_CHIPS_NUM_NBITS) // 2^CODE_PHASE_STEP_CHIPS_NUM_NBITS
#define PHASE_CARR_MAX 2147483648 // 2^(31) The phase is represented as a 32-bit vector in 1.31 format
#define PHASE_CARR_MAX_div_PI 683565275.5764316 // 2^(31)/pi
#define TWO_PI 6.283185307179586
#define LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT 0x20000000
#define LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER 0x10000000
#define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000
#define TEST_REGISTER_TRACK_WRITEVAL 0x55AA
#ifndef TEMP_FAILURE_RETRY
#define TEMP_FAILURE_RETRY(exp) \
({ \
@ -72,7 +58,8 @@
Fpga_Multicorrelator_8sc::Fpga_Multicorrelator_8sc(int32_t n_correlators,
std::string device_name, uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot,
uint32_t multicorr_type, uint32_t code_samples_per_chip)
uint32_t code_samples_per_chip)
{
d_n_correlators = n_correlators;
d_device_name = std::move(device_name);
@ -114,10 +101,12 @@ Fpga_Multicorrelator_8sc::Fpga_Multicorrelator_8sc(int32_t n_correlators,
d_code_length_chips = code_length_chips;
d_ca_codes = ca_codes;
d_data_codes = data_codes;
d_multicorr_type = multicorr_type;
d_code_samples_per_chip = code_samples_per_chip;
d_code_length_samples = d_code_length_chips * d_code_samples_per_chip;
d_secondary_code_enabled = false;
DLOG(INFO) << "TRACKING FPGA CLASS CREATED";
}
@ -139,8 +128,8 @@ Fpga_Multicorrelator_8sc::~Fpga_Multicorrelator_8sc()
uint64_t Fpga_Multicorrelator_8sc::read_sample_counter()
{
uint64_t sample_counter_tmp, sample_counter_msw_tmp;
sample_counter_tmp = d_map_base[SAMPLE_COUNTER_REG_ADDR_LSW];
sample_counter_msw_tmp = d_map_base[SAMPLE_COUNTER_REG_ADDR_MSW];
sample_counter_tmp = d_map_base[sample_counter_reg_addr_lsw];
sample_counter_msw_tmp = d_map_base[sample_counter_reg_addr_msw];
sample_counter_msw_tmp = sample_counter_msw_tmp << 32;
sample_counter_tmp = sample_counter_tmp + sample_counter_msw_tmp; // 2^32
return sample_counter_tmp;
@ -150,8 +139,8 @@ uint64_t Fpga_Multicorrelator_8sc::read_sample_counter()
void Fpga_Multicorrelator_8sc::set_initial_sample(uint64_t samples_offset)
{
d_initial_sample_counter = samples_offset;
d_map_base[INITIAL_COUNTER_VALUE_REG_ADDR_LSW] = (d_initial_sample_counter & 0xFFFFFFFF);
d_map_base[INITIAL_COUNTER_VALUE_REG_ADDR_MSW] = (d_initial_sample_counter >> 32) & 0xFFFFFFFF;
d_map_base[initial_counter_value_reg_addr_lsw] = (d_initial_sample_counter & 0xFFFFFFFF);
d_map_base[initial_counter_value_reg_addr_msw] = (d_initial_sample_counter >> 32) & 0xFFFFFFFF;
}
@ -205,6 +194,16 @@ void Fpga_Multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler(
std::cout << "Tracking_module Read failed to retrieve 4 bytes!" << std::endl;
std::cout << "Tracking_module Interrupt number " << irq_count << std::endl;
}
// release secondary code indices, keep channel locked
if (d_secondary_code_enabled == true)
{
d_map_base[drop_samples_reg_addr] = enable_secondary_code; // keep secondary code enabled
}
else
{
d_map_base[drop_samples_reg_addr] = 0; // block samples
}
Fpga_Multicorrelator_8sc::read_tracking_gps_results();
}
@ -233,7 +232,7 @@ bool Fpga_Multicorrelator_8sc::free()
void Fpga_Multicorrelator_8sc::set_channel(uint32_t channel)
{
char device_io_name[MAX_LENGTH_DEVICEIO_NAME]; // driver io name
char device_io_name[max_length_deviceio_name]; // driver io name
d_channel = channel;
// open the device corresponding to the assigned channel
@ -243,9 +242,9 @@ void Fpga_Multicorrelator_8sc::set_channel(uint32_t channel)
devicebasetemp << numdevice;
mergedname = d_device_name + devicebasetemp.str();
if (mergedname.size() > MAX_LENGTH_DEVICEIO_NAME)
if (mergedname.size() > max_length_deviceio_name)
{
mergedname = mergedname.substr(0, MAX_LENGTH_DEVICEIO_NAME);
mergedname = mergedname.substr(0, max_length_deviceio_name);
}
mergedname.copy(device_io_name, mergedname.size() + 1);
@ -257,7 +256,7 @@ void Fpga_Multicorrelator_8sc::set_channel(uint32_t channel)
LOG(WARNING) << "Cannot open deviceio" << device_io_name;
std::cout << "Cannot open deviceio" << device_io_name << std::endl;
}
d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, PAGE_SIZE,
d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, page_size,
PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0));
if (d_map_base == reinterpret_cast<void *>(-1))
@ -268,7 +267,7 @@ void Fpga_Multicorrelator_8sc::set_channel(uint32_t channel)
}
// sanity check: check test register
uint32_t writeval = TEST_REGISTER_TRACK_WRITEVAL;
uint32_t writeval = test_register_track_writeval;
uint32_t readval;
readval = Fpga_Multicorrelator_8sc::fpga_acquisition_test_register(writeval);
if (writeval != readval)
@ -288,9 +287,9 @@ uint32_t Fpga_Multicorrelator_8sc::fpga_acquisition_test_register(
{
uint32_t readval = 0;
// write value to test register
d_map_base[TEST_REG_ADDR] = writeval;
d_map_base[test_reg_addr] = writeval;
// read value from test register
readval = d_map_base[TEST_REG_ADDR];
readval = d_map_base[test_reg_addr];
// return read value
return readval;
}
@ -300,21 +299,21 @@ void Fpga_Multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int32_t PR
{
uint32_t k;
d_map_base[PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER;
d_map_base[prog_mems_addr] = local_code_fpga_clear_address_counter;
for (k = 0; k < d_code_length_samples; k++)
{
d_map_base[PROG_MEMS_ADDR] = d_ca_codes[(d_code_length_samples * (PRN - 1)) + k];
d_map_base[prog_mems_addr] = d_ca_codes[(d_code_length_samples * (PRN - 1)) + k];
}
if (d_track_pilot)
{
d_map_base[PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER;
d_map_base[prog_mems_addr] = local_code_fpga_clear_address_counter;
for (k = 0; k < d_code_length_samples; k++)
{
d_map_base[PROG_MEMS_ADDR] = d_data_codes[(d_code_length_samples * (PRN - 1)) + k];
d_map_base[prog_mems_addr] = d_data_codes[(d_code_length_samples * (PRN - 1)) + k];
}
}
d_map_base[CODE_LENGTH_MINUS_1_REG_ADDR] = (d_code_length_samples)-1; // number of samples - 1
d_map_base[code_length_minus_1_reg_addr] = (d_code_length_samples)-1; // number of samples - 1
}
@ -340,7 +339,7 @@ void Fpga_Multicorrelator_8sc::fpga_compute_code_shift_parameters(void)
frac_part = frac_part + 1.0; // fmod operator does not work as in Matlab with negative numbers
}
d_initial_interp_counter[i] = static_cast<uint32_t>(floor(MAX_CODE_RESAMPLER_COUNTER * frac_part));
d_initial_interp_counter[i] = static_cast<uint32_t>(floor(max_code_resampler_counter * frac_part));
}
if (d_track_pilot)
{
@ -357,7 +356,7 @@ void Fpga_Multicorrelator_8sc::fpga_compute_code_shift_parameters(void)
{
frac_part = frac_part + 1.0; // fmod operator does not work as in Matlab with negative numbers
}
d_initial_interp_counter[d_n_correlators] = static_cast<uint32_t>(floor(MAX_CODE_RESAMPLER_COUNTER * frac_part));
d_initial_interp_counter[d_n_correlators] = static_cast<uint32_t>(floor(max_code_resampler_counter * frac_part));
}
}
@ -366,13 +365,13 @@ void Fpga_Multicorrelator_8sc::fpga_configure_code_parameters_in_fpga(void)
{
for (uint32_t i = 0; i < d_n_correlators; i++)
{
d_map_base[INITIAL_INDEX_REG_BASE_ADDR + i] = d_initial_index[i];
d_map_base[INITIAL_INTERP_COUNTER_REG_BASE_ADDR + i] = d_initial_interp_counter[i];
d_map_base[initial_index_reg_base_addr + i] = d_initial_index[i];
d_map_base[initial_interp_counter_reg_base_addr + i] = d_initial_interp_counter[i];
}
if (d_track_pilot)
{
d_map_base[INITIAL_INDEX_REG_BASE_ADDR + d_n_correlators] = d_initial_index[d_n_correlators];
d_map_base[INITIAL_INTERP_COUNTER_REG_BASE_ADDR + d_n_correlators] = d_initial_interp_counter[d_n_correlators];
d_map_base[initial_index_reg_base_addr + d_n_correlators] = d_initial_index[d_n_correlators];
d_map_base[initial_interp_counter_reg_base_addr + d_n_correlators] = d_initial_interp_counter[d_n_correlators];
}
}
@ -381,8 +380,8 @@ void Fpga_Multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(void)
{
float d_rem_carrier_phase_in_rad_temp;
d_code_phase_step_chips_num = static_cast<uint32_t>(roundf(MAX_CODE_RESAMPLER_COUNTER * d_code_phase_step_chips));
d_code_phase_rate_step_chips_num = static_cast<uint32_t>(roundf(MAX_CODE_RESAMPLER_COUNTER * d_code_phase_rate_step_chips));
d_code_phase_step_chips_num = static_cast<uint32_t>(roundf(max_code_resampler_counter * d_code_phase_step_chips));
d_code_phase_rate_step_chips_num = static_cast<uint32_t>(roundf(max_code_resampler_counter * d_code_phase_rate_step_chips));
if (d_rem_carrier_phase_in_rad > M_PI)
{
@ -397,25 +396,25 @@ void Fpga_Multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(void)
d_rem_carrier_phase_in_rad_temp = d_rem_carrier_phase_in_rad;
}
d_rem_carr_phase_rad_int = static_cast<int32_t>(roundf((d_rem_carrier_phase_in_rad_temp)*PHASE_CARR_MAX_div_PI));
d_phase_step_rad_int = static_cast<int32_t>(roundf((d_phase_step_rad)*PHASE_CARR_MAX_div_PI)); // the FPGA accepts a range for the phase step between -pi and +pi
d_carrier_phase_rate_step_rad_int = static_cast<int32_t>(roundf((d_carrier_phase_rate_step_rad)*PHASE_CARR_MAX_div_PI));
d_rem_carr_phase_rad_int = static_cast<int32_t>(roundf((d_rem_carrier_phase_in_rad_temp)*PHASE_CARR_MAX_DIV_PI));
d_phase_step_rad_int = static_cast<int32_t>(roundf((d_phase_step_rad)*PHASE_CARR_MAX_DIV_PI)); // the FPGA accepts a range for the phase step between -pi and +pi
d_carrier_phase_rate_step_rad_int = static_cast<int32_t>(roundf((d_carrier_phase_rate_step_rad)*PHASE_CARR_MAX_DIV_PI));
}
void Fpga_Multicorrelator_8sc::fpga_configure_signal_parameters_in_fpga(void)
{
d_map_base[CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR] = d_code_phase_step_chips_num; // code phase step
d_map_base[code_phase_step_chips_num_reg_addr] = d_code_phase_step_chips_num; // code phase step
d_map_base[CODE_PHASE_STEP_CHIPS_RATE] = d_code_phase_rate_step_chips_num; // code phase step rate
d_map_base[code_phase_step_chips_rate_reg_addr] = d_code_phase_rate_step_chips_num; // code phase step rate
d_map_base[NSAMPLES_MINUS_1_REG_ADDR] = d_correlator_length_samples - 1; // number of samples
d_map_base[nsamples_minus_1_reg_addr] = d_correlator_length_samples - 1; // number of samples
d_map_base[REM_CARR_PHASE_RAD_REG_ADDR] = d_rem_carr_phase_rad_int; // initial nco phase
d_map_base[rem_carr_phase_rad_reg_addr] = d_rem_carr_phase_rad_int; // initial nco phase
d_map_base[PHASE_STEP_RAD_REG_ADDR] = d_phase_step_rad_int; // nco phase step
d_map_base[phase_step_rad_reg_addr] = d_phase_step_rad_int; // nco phase step
d_map_base[PHASE_STEP_RATE_REG_ADDR] = d_carrier_phase_rate_step_rad_int; // nco phase step rate
d_map_base[phase_step_rate_reg_addr] = d_carrier_phase_rate_step_rad_int; // nco phase step rate
}
@ -429,7 +428,7 @@ void Fpga_Multicorrelator_8sc::fpga_launch_multicorrelator_fpga(void)
std::cerr << "Error launching the FPGA multicorrelator" << std::endl;
}
// writing 1 to reg 14 launches the tracking
d_map_base[START_FLAG_ADDR] = 1;
d_map_base[start_flag_addr] = 1;
}
@ -440,14 +439,14 @@ void Fpga_Multicorrelator_8sc::read_tracking_gps_results(void)
for (uint32_t k = 0; k < d_n_correlators; k++)
{
readval_real = d_map_base[RESULT_REG_REAL_BASE_ADDR + k];
readval_imag = d_map_base[RESULT_REG_IMAG_BASE_ADDR + k];
readval_real = d_map_base[result_reg_real_base_addr + k];
readval_imag = d_map_base[result_reg_imag_base_addr + k];
d_corr_out[k] = gr_complex(readval_real, readval_imag);
}
if (d_track_pilot)
{
readval_real = d_map_base[RESULT_REG_REAL_BASE_ADDR + d_n_correlators];
readval_imag = d_map_base[RESULT_REG_IMAG_BASE_ADDR + d_n_correlators];
readval_real = d_map_base[result_reg_real_base_addr + d_n_correlators];
readval_imag = d_map_base[result_reg_imag_base_addr + d_n_correlators];
d_Prompt_Data[0] = gr_complex(readval_real, readval_imag);
}
}
@ -456,15 +455,17 @@ void Fpga_Multicorrelator_8sc::read_tracking_gps_results(void)
void Fpga_Multicorrelator_8sc::unlock_channel(void)
{
// unlock the channel to let the next samples go through
d_map_base[DROP_SAMPLES_REG_ADDR] = 1; // unlock the channel
d_map_base[STOP_TRACKING_REG_ADDR] = 1; // set the tracking module back to idle
d_map_base[drop_samples_reg_addr] = drop_samples; // unlock the channel and disable secondary codes
d_map_base[stop_tracking_reg_addr] = 1; // set the tracking module back to idle
d_secondary_code_enabled = false;
}
void Fpga_Multicorrelator_8sc::close_device()
{
auto *aux = const_cast<uint32_t *>(d_map_base);
if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1)
if (munmap(static_cast<void *>(aux), page_size) == -1)
{
std::cout << "Failed to unmap memory uio" << std::endl;
}
@ -475,5 +476,97 @@ void Fpga_Multicorrelator_8sc::close_device()
void Fpga_Multicorrelator_8sc::lock_channel(void)
{
// lock the channel for processing
d_map_base[DROP_SAMPLES_REG_ADDR] = 0; // lock the channel
d_map_base[drop_samples_reg_addr] = 0; // lock the channel
}
void Fpga_Multicorrelator_8sc::set_secondary_code_lengths(uint32_t secondary_code_0_length, uint32_t secondary_code_1_length)
{
d_secondary_code_0_length = secondary_code_0_length;
d_secondary_code_1_length = secondary_code_1_length;
uint32_t secondary_code_length_0_minus_1 = d_secondary_code_0_length - 1;
uint32_t secondary_code_length_1_minus_1 = d_secondary_code_1_length - 1;
d_map_base[secondary_code_lengths_reg_addr] = secondary_code_length_1_minus_1 * 256 + secondary_code_length_0_minus_1;
}
void Fpga_Multicorrelator_8sc::update_prn_code_length(uint32_t first_prn_length, uint32_t next_prn_length)
{
d_map_base[first_prn_length_minus_1_reg_addr] = first_prn_length - 1;
d_map_base[next_prn_length_minus_1_reg_addr] = next_prn_length - 1;
}
void Fpga_Multicorrelator_8sc::initialize_secondary_code(uint32_t secondary_code, std::string *secondary_code_string)
{
uint32_t secondary_code_length;
uint32_t reg_addr;
if (secondary_code == 0)
{
secondary_code_length = d_secondary_code_0_length;
reg_addr = prog_secondary_code_0_data_reg_addr;
}
else
{
secondary_code_length = d_secondary_code_1_length;
reg_addr = prog_secondary_code_1_data_reg_addr;
}
Fpga_Multicorrelator_8sc::write_secondary_code(secondary_code_length, secondary_code_string, reg_addr);
}
void Fpga_Multicorrelator_8sc::write_secondary_code(uint32_t secondary_code_length, std::string *secondary_code_string, uint32_t reg_addr)
{
uint32_t num_words = ceil(((float)secondary_code_length) / secondary_code_word_size);
uint32_t last_word_size = secondary_code_length % secondary_code_word_size;
if (last_word_size == 0)
{
last_word_size = secondary_code_word_size;
}
uint32_t write_val = 0U;
uint32_t pow_k;
uint32_t mem_addr;
if (num_words > 1)
{
for (mem_addr = 0; mem_addr < num_words - 1; mem_addr++)
{
write_val = 0U;
pow_k = 1;
for (unsigned int k = 0; k < secondary_code_word_size; k++)
{
std::string string_tmp(1, secondary_code_string->at(mem_addr * secondary_code_word_size + k));
write_val = write_val | std::stoi(string_tmp) * pow_k;
pow_k = pow_k * 2;
}
write_val = write_val | mem_addr * secondary_code_addr_bits | secondary_code_wr_strobe;
d_map_base[reg_addr] = write_val;
}
}
write_val = 0U;
pow_k = 1;
mem_addr = num_words - 1;
for (unsigned int k = 0; k < last_word_size; k++)
{
std::string string_tmp(1, secondary_code_string->at(mem_addr * secondary_code_word_size + k));
write_val = write_val | std::stoi(string_tmp) * pow_k;
pow_k = pow_k * 2;
}
write_val = write_val | (mem_addr * secondary_code_addr_bits) | (secondary_code_wr_strobe);
d_map_base[reg_addr] = write_val;
}
void Fpga_Multicorrelator_8sc::enable_secondary_codes()
{
d_map_base[drop_samples_reg_addr] = init_secondary_code_addresses | enable_secondary_code; // enable secondary codes and clear secondary code indices
d_secondary_code_enabled = true;
}
void Fpga_Multicorrelator_8sc::disable_secondary_codes()
{
// this function is to be called before starting the tracking process in order to disable the secondary codes by default
d_map_base[drop_samples_reg_addr] = drop_samples;
}

View File

@ -29,7 +29,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
@ -40,33 +40,9 @@
#include <gnuradio/block.h>
#include <cstdint>
// FPGA register addresses
// write addresses
#define CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR 0
#define INITIAL_INDEX_REG_BASE_ADDR 1
#define INITIAL_INTERP_COUNTER_REG_BASE_ADDR 7
#define NSAMPLES_MINUS_1_REG_ADDR 13
#define CODE_LENGTH_MINUS_1_REG_ADDR 14
#define REM_CARR_PHASE_RAD_REG_ADDR 15
#define PHASE_STEP_RAD_REG_ADDR 16
#define PROG_MEMS_ADDR 17
#define DROP_SAMPLES_REG_ADDR 18
#define INITIAL_COUNTER_VALUE_REG_ADDR_LSW 19
#define INITIAL_COUNTER_VALUE_REG_ADDR_MSW 20
#define CODE_PHASE_STEP_CHIPS_RATE 21
#define PHASE_STEP_RATE_REG_ADDR 22
#define STOP_TRACKING_REG_ADDR 23
#define INT_ON_RST_REG_ADDR 24 // cause interrupt on reset to prevent deadlock
#define START_FLAG_ADDR 30
// read-write addresses
#define TEST_REG_ADDR 31
// read addresses
#define RESULT_REG_REAL_BASE_ADDR 1
#define RESULT_REG_IMAG_BASE_ADDR 7
#define SAMPLE_COUNTER_REG_ADDR_LSW 13
#define SAMPLE_COUNTER_REG_ADDR_MSW 14
// floating point math constants related to the parameters that are written in the FPGA
#define PHASE_CARR_MAX_DIV_PI 683565275.5764316 // 2^(31)/pi
#define TWO_PI 6.283185307179586
/*!
* \brief Class that implements carrier wipe-off and correlators.
@ -74,27 +50,154 @@
class Fpga_Multicorrelator_8sc
{
public:
/*!
* \brief Constructor
*/
Fpga_Multicorrelator_8sc(int32_t n_correlators, std::string device_name,
uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, uint32_t multicorr_type, uint32_t code_samples_per_chip);
uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, uint32_t code_samples_per_chip);
/*!
* \brief Destructor
*/
~Fpga_Multicorrelator_8sc();
/*!
* \brief Configure pointers to the FPGA multicorrelator results
*/
void set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data);
/*!
* \brief Configure the local code in the FPGA multicorrelator
*/
void set_local_code_and_taps(
float *shifts_chips, float *prompt_data_shift, int32_t PRN);
/*!
* \brief Configure code phase and code rate parameters in the FPGA
*/
void update_local_code();
/*!
* \brief Perform a multicorrelation
*/
void Carrier_wipeoff_multicorrelator_resampler(
float rem_carrier_phase_in_rad, float phase_step_rad,
float carrier_phase_rate_step_rad,
float rem_code_phase_chips, float code_phase_step_chips,
float code_phase_rate_step_chips,
int32_t signal_length_samples);
/*!
* \brief Stop the correlation process in the FPGA and free code phase and code rate parameters
*/
bool free();
/*!
* \brief Set channel number and open the FPGA device driver
*/
void set_channel(uint32_t channel);
/*!
* \brief Set the initial sample number where the tracking process begins
*/
void set_initial_sample(uint64_t samples_offset);
/*!
* \brief Read the sample counter in the FPGA
*/
uint64_t read_sample_counter();
/*!
* \brief Start the tracking process in the FPGA
*/
void lock_channel(void);
/*!
* \brief finish the tracking process in the FPGA
*/
void unlock_channel(void);
/*!
* \brief Set the secondary code length in the FPGA. This is only used when extended coherent integration
* is enabled in the FPGA. If tracking the pilot is enabled then secondary_code_0_length is the length of the pilot
* secondary code and secondary_code_1_length is the length of the data secondary code. If tracking the pilot is disabled
* then secondary_code_0_length is the length of the data secondary code, and secondary_code_1_length must be set to zero.
*/
void set_secondary_code_lengths(uint32_t secondary_code_0_length, uint32_t secondary_code_1_length);
/*!
* \brief Initialize the secondary code in the FPGA. If tracking the pilot is enabled then the pilot secondary code is
* configured when secondary_code = 0 and the data secondary code is configured when secondary_code = 1. If tracking the
* pilot is disabled then the data secondary code is configured when secondary code = 0.
*/
void initialize_secondary_code(uint32_t secondary_code, std::string *secondary_code_string);
/*!
* \brief Set the PRN length in the FPGA in number of samples. This function is only used then extended coherent integration is enabled in the
* FPGA. The FPGA allows for the configuration of two PRN lengths. When the length of the extended coherent integration is bigger than the
* length of the PRN code, the FPGA uses the first_length_secondary_code as the length of the PRN code immediately following the beginning
* of the extended coherent integration, and the next_length_secondary_code as the length of the remaining PRN codes.
* The purpose of this is to have the option to allow the FPGA to compensate for a possible deviation between the nominal value of the PRN
* code length and the measured PRN code length in the PRN immediately following the start of the coherent integration only.
* If this option is not used then write the same value to first_length_secondary_code and next_length_secondary_code.
*/
void update_prn_code_length(uint32_t first_length_secondary_code, uint32_t next_length_secondary_code);
/*!
* \brief Enable the use of secondary codes in the FPGA
*/
void enable_secondary_codes();
/*!
* \brief Disable the use of secondary codes in the FPGA
*/
void disable_secondary_codes();
private:
// FPGA register addresses
// write addresses
static const uint32_t code_phase_step_chips_num_reg_addr = 0;
static const uint32_t initial_index_reg_base_addr = 1;
static const uint32_t initial_interp_counter_reg_base_addr = 7;
static const uint32_t nsamples_minus_1_reg_addr = 13;
static const uint32_t code_length_minus_1_reg_addr = 14;
static const uint32_t rem_carr_phase_rad_reg_addr = 15;
static const uint32_t phase_step_rad_reg_addr = 16;
static const uint32_t prog_mems_addr = 17;
static const uint32_t drop_samples_reg_addr = 18;
static const uint32_t initial_counter_value_reg_addr_lsw = 19;
static const uint32_t initial_counter_value_reg_addr_msw = 20;
static const uint32_t code_phase_step_chips_rate_reg_addr = 21;
static const uint32_t phase_step_rate_reg_addr = 22;
static const uint32_t stop_tracking_reg_addr = 23;
static const uint32_t secondary_code_lengths_reg_addr = 25;
static const uint32_t prog_secondary_code_0_data_reg_addr = 26;
static const uint32_t prog_secondary_code_1_data_reg_addr = 27;
static const uint32_t first_prn_length_minus_1_reg_addr = 28;
static const uint32_t next_prn_length_minus_1_reg_addr = 29;
static const uint32_t start_flag_addr = 30;
// read-write addresses
static const uint32_t test_reg_addr = 31;
// read addresses
static const uint32_t result_reg_real_base_addr = 1;
static const uint32_t result_reg_imag_base_addr = 7;
static const uint32_t sample_counter_reg_addr_lsw = 13;
static const uint32_t sample_counter_reg_addr_msw = 14;
// FPGA-related constants
static const uint32_t secondary_code_word_size = 20; // the secondary codes are written in to the FPGA in words of secondary_code_word_size bits
static const uint32_t secondary_code_wr_strobe = 0x800000; // write strobe position in the secondary code write register
static const uint32_t secondary_code_addr_bits = 0x100000; // memory address position in the secondary code write register
static const uint32_t drop_samples = 1; // bit 0 of drop_samples_reg_addr
static const uint32_t enable_secondary_code = 2; // bit 1 of drop_samples_reg_addr
static const uint32_t init_secondary_code_addresses = 4; // bit 2 of drop_samples_reg_addr
static const uint32_t page_size = 0x10000;
static const uint32_t max_length_deviceio_name = 50;
static const uint32_t max_code_resampler_counter = 1 << 20; // 2^(number of bits of precision of the code resampler)
static const uint32_t local_code_fpga_clear_address_counter = 0x10000000;
static const uint32_t test_register_track_writeval = 0x55AA;
gr_complex *d_corr_out;
gr_complex *d_Prompt_Data;
float *d_shifts_chips;
@ -116,6 +219,8 @@ private:
float d_rem_carrier_phase_in_rad;
float d_phase_step_rad;
float d_carrier_phase_rate_step_rad;
uint32_t d_code_samples_per_chip;
bool d_track_pilot;
// configuration data computed in the format that the FPGA expects
uint32_t *d_initial_index;
@ -131,13 +236,14 @@ private:
std::string d_device_name;
uint32_t d_device_base;
// PRN codes
int32_t *d_ca_codes;
int32_t *d_data_codes;
uint32_t d_code_samples_per_chip;
bool d_track_pilot;
uint32_t d_multicorr_type;
// secondary code configuration
uint32_t d_secondary_code_0_length;
uint32_t d_secondary_code_1_length;
bool d_secondary_code_enabled;
// private functions
uint32_t fpga_acquisition_test_register(uint32_t writeval);
@ -149,6 +255,7 @@ private:
void fpga_launch_multicorrelator_fpga(void);
void read_tracking_gps_results(void);
void close_device(void);
void write_secondary_code(uint32_t secondary_code_length, std::string *secondary_code_string, uint32_t reg_addr);
};
#endif /* GNSS_SDR_FPGA_MULTICORRELATOR_H_ */

View File

@ -43,8 +43,6 @@
#include <unistd.h> // for write, close, read, ssize_t
#define PAGE_SIZE 0x10000 // default page size for the multicorrelator memory map
#define TEST_REG_SANITY_CHECK 0x55AA // value to check the presence of the test register (to detect the hw)
#ifndef TEMP_FAILURE_RETRY
#define TEMP_FAILURE_RETRY(exp) \
({ \
@ -151,7 +149,7 @@ void gnss_sdr_fpga_sample_counter::open_device()
LOG(WARNING) << "Cannot open deviceio" << device_name;
std::cout << "Counter-Intr: cannot open deviceio" << device_name << std::endl;
}
map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, PAGE_SIZE,
map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, page_size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
if (map_base == reinterpret_cast<void *>(-1))
@ -161,7 +159,7 @@ void gnss_sdr_fpga_sample_counter::open_device()
}
// sanity check : check test register
uint32_t writeval = TEST_REG_SANITY_CHECK;
uint32_t writeval = test_reg_sanity_check;
uint32_t readval;
readval = gnss_sdr_fpga_sample_counter::test_register(writeval);
if (writeval != readval)
@ -181,7 +179,7 @@ void gnss_sdr_fpga_sample_counter::close_device()
map_base[2] = 0; // disable the generation of the interrupt in the device
auto *aux = const_cast<uint32_t *>(map_base);
if (munmap(static_cast<void *>(aux), PAGE_SIZE) == -1)
if (munmap(static_cast<void *>(aux), page_size) == -1)
{
std::cout << "Failed to unmap memory uio" << std::endl;
}

View File

@ -55,6 +55,9 @@ public:
gr_vector_void_star &output_items);
private:
static const uint32_t page_size = 0x10000; // default page size for the multicorrelator memory map
static const uint32_t test_reg_sanity_check = 0x55AA; // value to check the presence of the test register (to detect the hw)
friend gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms);
gnss_sdr_fpga_sample_counter(double _fs, int32_t _interval_ms);
uint32_t test_register(uint32_t writeval);