1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-09-10 06:46:03 +00:00

Enable multi-band GNSS reception via MAX2771

This commit is contained in:
Marc Majoral
2025-07-09 14:40:22 +02:00
committed by Carles Fernandez
parent 3c77662723
commit 1203acbd69
4 changed files with 105 additions and 37 deletions

View File

@@ -42,10 +42,13 @@ MAX2771EVKITSignalSourceFPGA::MAX2771EVKITSignalSourceFPGA(const ConfigurationIn
Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused))) Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused)))
: SignalSourceBase(configuration, role, "MAX2771_EVKIT_Signal_Source_FPGA"s), : SignalSourceBase(configuration, role, "MAX2771_EVKIT_Signal_Source_FPGA"s),
freq_(configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ))), freq_(configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ))),
freq0_(configuration->property(role + ".freq0", freq_)),
freq1_(configuration->property(role + ".freq1", static_cast<uint64_t>(GPS_L5_FREQ_HZ))),
sample_rate_(configuration->property(role + ".sampling_frequency", default_sampling_rate)), sample_rate_(configuration->property(role + ".sampling_frequency", default_sampling_rate)),
RF_channels_(configuration->property(role + ".RF_channels", 1)),
in_stream_(in_stream), in_stream_(in_stream),
out_stream_(out_stream), out_stream_(out_stream),
bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)), bandwidth_(configuration->property(role + ".bandwidth", DEFAULT_BANDWIDTH)),
filter_order_(configuration->property(role + ".filter_order", default_filter_order)), filter_order_(configuration->property(role + ".filter_order", default_filter_order)),
gain_in_(configuration->property(role + ".PGA_gain", default_PGA_gain_value)), gain_in_(configuration->property(role + ".PGA_gain", default_PGA_gain_value)),
item_size_(sizeof(int8_t)), item_size_(sizeof(int8_t)),
@@ -62,13 +65,29 @@ MAX2771EVKITSignalSourceFPGA::MAX2771EVKITSignalSourceFPGA(const ConfigurationIn
#endif #endif
{ {
// some basic checks // some basic checks
if (freq_ != GPS_L1_FREQ_HZ and freq_ != GPS_L2_FREQ_HZ and freq_ != GPS_L5_FREQ_HZ) if (RF_channels_ > MAX_NUM_FREQ_BANDS)
{ {
std::cout << "Configuration parameter freq should take values " << GPS_L1_FREQ_HZ << ", " << GPS_L2_FREQ_HZ << ", or " << GPS_L5_FREQ_HZ << "\n"; std::cout << "Configuration parameter RF_channels supports values up to and including " << MAX_NUM_FREQ_BANDS << "\n";
std::cout << "Error: provided value freq = " << freq_ << " is not among valid values\n"; std::cout << "Error: provided value RF_channels = " << RF_channels_ << " is not among valid values\n";
std::cout << " This parameter has been set to its default value freq = " << GPS_L1_FREQ_HZ << '\n'; std::cout << " This parameter has been set to its default value RF_channels = " << DEFAULT_NUM_FREQ_BANDS << '\n';
LOG(WARNING) << "Invalid configuration value for freq parameter. Set to freq = " << GPS_L1_FREQ_HZ; LOG(WARNING) << "Invalid configuration value for RF_channels parameter. Set to RF_channels = " << DEFAULT_NUM_FREQ_BANDS;
freq_ = GPS_L1_FREQ_HZ; }
if (freq0_ != GPS_L1_FREQ_HZ)
{
std::string freq_name = (RF_channels_ == 1) ? "freq" : "freq0";
std::cout << "Configuration parameter " << freq_name << " should take values " << GPS_L1_FREQ_HZ << ", " << GPS_L2_FREQ_HZ << ", or " << GPS_L5_FREQ_HZ << "\n";
std::cout << "Error: provided value " << freq_name << " = " << freq0_ << " is not among valid values\n";
std::cout << " This parameter has been set to its default value " << freq_name << " = " << GPS_L1_FREQ_HZ << '\n';
LOG(WARNING) << "Invalid configuration value for " << freq_name << " parameter. Set to " << freq_name << " = " << GPS_L1_FREQ_HZ;
freq0_ = GPS_L1_FREQ_HZ;
}
if (freq1_ != GPS_L2_FREQ_HZ and freq1_ != GPS_L5_FREQ_HZ)
{
std::cout << "Configuration parameter freq1 should take values " << GPS_L1_FREQ_HZ << ", " << GPS_L2_FREQ_HZ << ", or " << GPS_L5_FREQ_HZ << "\n";
std::cout << "Error: provided value freq1 = " << freq1_ << " is not among valid values\n";
std::cout << " This parameter has been set to its default value freq1 = " << GPS_L5_FREQ_HZ << '\n';
LOG(WARNING) << "Invalid configuration value for freq1 parameter. Set to freq1 = " << GPS_L5_FREQ_HZ;
freq1_ = GPS_L5_FREQ_HZ;
} }
if (sample_rate_ != 4092000 and sample_rate_ != 8184000 and sample_rate_ != 16368000 and sample_rate_ != 32736000) if (sample_rate_ != 4092000 and sample_rate_ != 8184000 and sample_rate_ != 16368000 and sample_rate_ != 32736000)
{ {
@@ -82,9 +101,9 @@ MAX2771EVKITSignalSourceFPGA::MAX2771EVKITSignalSourceFPGA(const ConfigurationIn
{ {
std::cout << "Configuration parameter bandwidth can only take the following values: 2500000, 4200000, 8700000, 16400000, 23400000, and 36000000 Hz\n"; std::cout << "Configuration parameter bandwidth can only take the following values: 2500000, 4200000, 8700000, 16400000, 23400000, and 36000000 Hz\n";
std::cout << "Error: provided value bandwidth = " << bandwidth_ << " is not among valid values\n"; std::cout << "Error: provided value bandwidth = " << bandwidth_ << " is not among valid values\n";
std::cout << " This parameter has been set to its default value bandwidth = " << default_bandwidth << '\n'; std::cout << " This parameter has been set to its default value bandwidth = " << DEFAULT_BANDWIDTH << '\n';
LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth = " << default_bandwidth; LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth = " << DEFAULT_BANDWIDTH;
bandwidth_ = default_bandwidth; bandwidth_ = DEFAULT_BANDWIDTH;
} }
if (filter_order_ != 3 and filter_order_ != 5) if (filter_order_ != 3 and filter_order_ != 5)
{ {
@@ -103,29 +122,52 @@ MAX2771EVKITSignalSourceFPGA::MAX2771EVKITSignalSourceFPGA(const ConfigurationIn
gain_in_ = default_PGA_gain_value; gain_in_ = default_PGA_gain_value;
} }
std::vector<uint32_t> register_values = setup_regs(); // Create and initialize the SPI interface
spidev_fpga = std::make_shared<Fpga_spidev>(); spidev_fpga = std::make_shared<Fpga_spidev>();
if (spidev_fpga->SPI_open()) // configure analog-front-end for frequency band 0
std::vector<uint32_t> register_values = setup_regs(freq0_);
if (spidev_fpga->SPI_open(FREQ_BAND_0_SPI_DEVICE_NAME))
{ {
std::cerr << "Cannot open SPI device\n"; std::cerr << "Cannot open " << FREQ_BAND_0_SPI_DEVICE_NAME << " device\n";
// stop the receiver queue->push(pmt::make_any(command_event_make(200, 0))); // stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
return; return;
} }
if (configure(register_values)) if (configure(register_values))
{ {
std::cerr << "Error configuring the MAX2771 device " << '\n'; std::cerr << "Error configuring the MAX2771 device " << '\n';
} }
if (spidev_fpga->SPI_close()) if (spidev_fpga->SPI_close())
{ {
std::cerr << "Error closing SPI device " << '\n'; std::cerr << "Error closing " << FREQ_BAND_0_SPI_DEVICE_NAME << " device\n";
} }
std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); // configure analog-front-end for frequency band 1 if enabled
if (RF_channels_ == MAX_NUM_FREQ_BANDS)
{
register_values = setup_regs(freq1_);
if (spidev_fpga->SPI_open(FREQ_BAND_1_SPI_DEVICE_NAME))
{
std::cerr << "Cannot open " << FREQ_BAND_1_SPI_DEVICE_NAME << " device\n";
queue->push(pmt::make_any(command_event_make(200, 0))); // stop the receiver
return;
}
if (configure(register_values))
{
std::cerr << "Error configuring the MAX2771 device " << '\n';
}
if (spidev_fpga->SPI_close())
{
std::cerr << "Error closing " << FREQ_BAND_1_SPI_DEVICE_NAME << " device\n";
}
}
// configure buffer monitor
std::string dump_filename = configuration->property(role + ".dump_filename", DEFAULT_BUFF_MON_FILENAME);
buffer_monitor_fpga = std::make_shared<Fpga_buffer_monitor>(NUM_FREQ_BANDS, dump_, dump_filename); buffer_monitor_fpga = std::make_shared<Fpga_buffer_monitor>(NUM_FREQ_BANDS, dump_, dump_filename);
thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); }); thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); });
@@ -141,7 +183,7 @@ MAX2771EVKITSignalSourceFPGA::MAX2771EVKITSignalSourceFPGA(const ConfigurationIn
} }
std::vector<uint32_t> MAX2771EVKITSignalSourceFPGA::setup_regs(void) std::vector<uint32_t> MAX2771EVKITSignalSourceFPGA::setup_regs(uint64_t freq)
{ {
auto register_values = std::vector<uint32_t>(MAX2771_NUM_REGS); auto register_values = std::vector<uint32_t>(MAX2771_NUM_REGS);
uint32_t LNA_mode = (LNA_active_) ? 0x0 : 0x2; uint32_t LNA_mode = (LNA_active_) ? 0x0 : 0x2;
@@ -274,7 +316,7 @@ std::vector<uint32_t> MAX2771EVKITSignalSourceFPGA::setup_regs(void)
0x0; // reserved 0x0; // reserved
uint32_t freq_sel; uint32_t freq_sel;
switch (freq_) switch (freq)
{ {
case static_cast<uint64_t>(GPS_L1_FREQ_HZ): case static_cast<uint64_t>(GPS_L1_FREQ_HZ):
freq_sel = 0x604; freq_sel = 0x604;
@@ -380,24 +422,43 @@ MAX2771EVKITSignalSourceFPGA::~MAX2771EVKITSignalSourceFPGA()
// cleanup and exit // cleanup and exit
if (rf_shutdown_) if (rf_shutdown_)
{ {
// stop analog-front-end for frequency band 0
chipen_ = false; chipen_ = false;
std::cout << "* MAX2771 Disabling RX streaming channels\n"; std::cout << "* MAX2771 Disabling RX streaming channels\n";
std::vector<uint32_t> register_values = setup_regs(); std::vector<uint32_t> register_values = setup_regs(freq0_);
if (spidev_fpga->SPI_open(FREQ_BAND_0_SPI_DEVICE_NAME))
if (spidev_fpga->SPI_open())
{ {
std::cerr << "Cannot open SPI device\n"; std::cerr << "Cannot open " << FREQ_BAND_0_SPI_DEVICE_NAME << " device\n";
return; return;
} }
if (configure(register_values)) if (configure(register_values))
{ {
std::cerr << "Error disabling the MAX2771 device " << '\n'; std::cerr << "Error disabling the MAX2771 device " << '\n';
} }
if (spidev_fpga->SPI_close()) if (spidev_fpga->SPI_close())
{ {
std::cerr << "Error closing SPI device " << '\n'; std::cerr << "Error closing " << FREQ_BAND_0_SPI_DEVICE_NAME << " device\n";
}
// stop analog-front-end for frequency band 1 if enabled
if (RF_channels_ == MAX_NUM_FREQ_BANDS)
{
std::cout << "* MAX2771 Disabling RX streaming channels\n";
register_values = setup_regs(freq1_);
if (spidev_fpga->SPI_open(FREQ_BAND_1_SPI_DEVICE_NAME))
{
std::cerr << "Cannot open " << FREQ_BAND_1_SPI_DEVICE_NAME << " device\n";
return;
}
if (configure(register_values))
{
std::cerr << "Error disabling the MAX2771 device " << '\n';
}
if (spidev_fpga->SPI_close())
{
std::cerr << "Error closing " << FREQ_BAND_1_SPI_DEVICE_NAME << " device\n";
}
} }
} }

View File

@@ -51,7 +51,7 @@ public:
~MAX2771EVKITSignalSourceFPGA(); ~MAX2771EVKITSignalSourceFPGA();
std::vector<uint32_t> setup_regs(void); std::vector<uint32_t> setup_regs(uint64_t freq);
inline size_t item_size() override inline size_t item_size() override
{ {
@@ -64,8 +64,12 @@ public:
gr::basic_block_sptr get_right_block() override; gr::basic_block_sptr get_right_block() override;
private: private:
const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat"); const std::string DEFAULT_BUFF_MON_FILENAME = std::string("FPGA_buffer_monitor_dump.dat");
const uint64_t default_bandwidth = 2500000; const std::string FREQ_BAND_0_SPI_DEVICE_NAME = std::string("/dev/spidev2.0"); // Switch UIO device name
const std::string FREQ_BAND_1_SPI_DEVICE_NAME = std::string("/dev/spidev1.0"); // Switch UIO device name
const uint32_t MAX_NUM_FREQ_BANDS = 2;
const uint32_t DEFAULT_NUM_FREQ_BANDS = 1;
const uint64_t DEFAULT_BANDWIDTH = 2500000;
const uint32_t default_filter_order = 5; const uint32_t default_filter_order = 5;
const uint64_t default_sampling_rate = 4092000; const uint64_t default_sampling_rate = 4092000;
const uint32_t default_PGA_gain_value = 0x3A; // default PGA gain when AGC is off const uint32_t default_PGA_gain_value = 0x3A; // default PGA gain when AGC is off
@@ -136,9 +140,12 @@ private:
std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga; std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga;
std::shared_ptr<Fpga_spidev> spidev_fpga; std::shared_ptr<Fpga_spidev> spidev_fpga;
uint64_t freq_; // frequency of local oscillator uint64_t freq_; // Tuning frequency in single-band mode
uint64_t freq0_; // Tuning frequency for band 0 when dual-band mode is enabled
uint64_t freq1_; // Tuning frequency for band 1 when dual-band mode is enabled
uint64_t sample_rate_; uint64_t sample_rate_;
uint32_t RF_channels_;
uint32_t in_stream_; uint32_t in_stream_;
uint32_t out_stream_; uint32_t out_stream_;
uint32_t bandwidth_; // 2500000, 4200000, 8700000, 16400000, 23400000, 36000000 uint32_t bandwidth_; // 2500000, 4200000, 8700000, 16400000, 23400000, 36000000

View File

@@ -22,11 +22,11 @@
#include <unistd.h> // for close() #include <unistd.h> // for close()
int Fpga_spidev::SPI_open() int Fpga_spidev::SPI_open(std::string spi_device_name)
{ {
if ((d_fd = open(SPI_DEVICE_NAME.c_str(), O_RDWR)) < 0) if ((d_fd = open(spi_device_name.c_str(), O_RDWR)) < 0)
{ {
std::cerr << "Failed to open the " << SPI_DEVICE_NAME << " device file \n"; std::cerr << "Failed to open the " << spi_device_name << " device file \n";
return -1; return -1;
} }

View File

@@ -44,7 +44,7 @@ public:
/*! /*!
* \brief Open the SPI device driver. * \brief Open the SPI device driver.
*/ */
int SPI_open(void); int SPI_open(std::string spi_device_name);
/*! /*!
* \brief Close the SPI device driver * \brief Close the SPI device driver
@@ -53,7 +53,7 @@ public:
private: private:
static const uint32_t SPI_SPEED = 250000; static const uint32_t SPI_SPEED = 250000;
const std::string SPI_DEVICE_NAME = std::string("/dev/spidev2.0"); // Switch UIO device name // const std::string SPI_DEVICE_NAME = std::string("/dev/spidev2.0"); // Switch UIO device name
int d_fd; int d_fd;
}; };