diff --git a/src/algorithms/acquisition/adapters/CMakeLists.txt b/src/algorithms/acquisition/adapters/CMakeLists.txt index 48168cf77..04654b424 100644 --- a/src/algorithms/acquisition/adapters/CMakeLists.txt +++ b/src/algorithms/acquisition/adapters/CMakeLists.txt @@ -129,6 +129,10 @@ if(ENABLE_FPGA) Volk::volk Volkgnsssdr::volkgnsssdr ) + target_include_directories(acquisition_adapters + PUBLIC + ${CMAKE_SOURCE_DIR}/src/core/libs + ) endif() target_include_directories(acquisition_adapters diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc index 2698278d1..5984e2afa 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc @@ -24,6 +24,7 @@ #include "galileo_e1_signal_replica.h" #include "gnss_sdr_flags.h" #include "gnss_sdr_make_unique.h" +#include "uio_fpga.h" #include #include // for fft_complex #include // for gr_complex @@ -77,11 +78,19 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( float nbits = ceilf(log2f(static_cast(code_length) * 2.0F)); uint32_t nsamples_total = pow(2, nbits); uint32_t 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"; + + // UIO device file + std::string device_io_name; std::string device_name = configuration->property(role + ".devicename", default_device_name); - acq_parameters.device_name = device_name; + // find the uio device file corresponding to the GNSS reset module + if (find_uio_dev_file_name(device_io_name, device_name, 0) < 0) + { + std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl; + throw std::exception(); + } + acq_parameters.device_name = device_io_name; + acq_parameters.samples_per_code = nsamples_total; acq_parameters.excludelimit = static_cast(1 + ceil((1.0 / GALILEO_E1_CODE_CHIP_RATE_CPS) * static_cast(fs_in))); diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h index b0416f5f4..8993fa2b7 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h @@ -183,6 +183,8 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: + const std::string default_device_name = "acquisition_S00_AXI"; // UIO device name + // 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; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc index 68b10bcf0..e0a06773d 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc @@ -24,6 +24,7 @@ #include "galileo_e5_signal_replica.h" #include "gnss_sdr_flags.h" #include "gnss_sdr_make_unique.h" +#include "uio_fpga.h" #include #include // for fft_complex #include // for gr_complex @@ -80,11 +81,19 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga( uint32_t nsamples_total = pow(2, nbits); uint32_t select_queue_Fpga = configuration->property(role + ".select_queue_Fpga", 1); acq_parameters.select_queue_Fpga = select_queue_Fpga; - std::string default_device_name = "/dev/uio0"; - std::string device_name = configuration->property(role + ".devicename", default_device_name); - acq_parameters.device_name = device_name; - acq_parameters.samples_per_code = nsamples_total; + // UIO device file + std::string device_io_name; + std::string device_name = configuration->property(role + ".devicename", default_device_name); + // find the uio device file corresponding to the GNSS reset module + if (find_uio_dev_file_name(device_io_name, device_name, 0) < 0) + { + std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl; + throw std::exception(); + } + acq_parameters.device_name = device_io_name; + + acq_parameters.samples_per_code = nsamples_total; acq_parameters.excludelimit = static_cast(1 + ceil((1.0 / GALILEO_E5A_CODE_CHIP_RATE_CPS) * static_cast(fs_in))); // compute all the GALILEO E5 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h index 8556a39d2..bae558662 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h @@ -191,6 +191,8 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: + const std::string default_device_name = "acquisition_S00_AXI"; // UIO device name + // 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; diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc index 58deb4e1f..2d56da775 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc @@ -24,6 +24,7 @@ #include "configuration_interface.h" #include "galileo_e5_signal_replica.h" #include "gnss_sdr_flags.h" +#include "uio_fpga.h" #include #include // for fft_complex #include // for gr_complex @@ -79,11 +80,19 @@ GalileoE5bPcpsAcquisitionFpga::GalileoE5bPcpsAcquisitionFpga(const Configuration uint32_t nsamples_total = pow(2, nbits); uint32_t select_queue_Fpga = configuration->property(role + ".select_queue_Fpga", 1); acq_parameters.select_queue_Fpga = select_queue_Fpga; - std::string default_device_name = "/dev/uio0"; - std::string device_name = configuration->property(role + ".devicename", default_device_name); - acq_parameters.device_name = device_name; - acq_parameters.samples_per_code = nsamples_total; + // UIO device file + std::string device_io_name; + std::string device_name = configuration->property(role + ".devicename", default_device_name); + // find the uio device file corresponding to the GNSS reset module + if (find_uio_dev_file_name(device_io_name, device_name, 0) < 0) + { + std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl; + throw std::exception(); + } + acq_parameters.device_name = device_io_name; + + acq_parameters.samples_per_code = nsamples_total; acq_parameters.excludelimit = static_cast(1 + ceil((1.0 / GALILEO_E5B_CODE_CHIP_RATE_CPS) * static_cast(fs_in))); // compute all the GALILEO E5b PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h index 73cf0e341..62de2fdc9 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h @@ -190,6 +190,9 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: + + const std::string default_device_name = "acquisition_S00_AXI"; // UIO device name + // 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; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc index aabc72051..164a7595e 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc @@ -27,6 +27,7 @@ #include "gnss_sdr_flags.h" #include "gnss_sdr_make_unique.h" #include "gps_sdr_signal_replica.h" +#include "uio_fpga.h" #include #include #include // for gr_complex @@ -72,9 +73,18 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( uint32_t nsamples_total = pow(2, nbits); uint32_t 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"; + + // UIO device file + std::string device_io_name; std::string device_name = configuration->property(role + ".devicename", default_device_name); - acq_parameters.device_name = device_name; + // find the uio device file corresponding to the GNSS reset module + if (find_uio_dev_file_name(device_io_name, device_name, 0) < 0) + { + std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl; + throw std::exception(); + } + acq_parameters.device_name = device_io_name; + acq_parameters.samples_per_code = nsamples_total; acq_parameters.excludelimit = static_cast(1 + ceil(GPS_L1_CA_CHIP_PERIOD_S * static_cast(fs_in))); diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h index 62afda2b0..880ce3a75 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h @@ -187,6 +187,8 @@ public: private: static const uint32_t NUM_PRNs = 32; + const std::string default_device_name = "acquisition_S00_AXI"; // UIO device name + // 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; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc index 5d752ec04..190cd6151 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc @@ -27,6 +27,7 @@ #include "gnss_sdr_make_unique.h" #include "gnss_synchro.h" #include "gps_l2c_signal_replica.h" +#include "uio_fpga.h" #include #include // for fft_complex #include // for gr_complex @@ -70,11 +71,19 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( unsigned int nsamples_total = pow(2, nbits); 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"; - std::string device_name = configuration->property(role + ".devicename", default_device_name); - acq_parameters.device_name = device_name; - acq_parameters.samples_per_code = nsamples_total; + // UIO device file + std::string device_io_name; + std::string device_name = configuration->property(role + ".devicename", default_device_name); + // find the uio device file corresponding to the GNSS reset module + if (find_uio_dev_file_name(device_io_name, device_name, 0) < 0) + { + std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl; + throw std::exception(); + } + acq_parameters.device_name = device_io_name; + + acq_parameters.samples_per_code = nsamples_total; acq_parameters.downsampling_factor = configuration->property(role + ".downsampling_factor", 1.0); acq_parameters.total_block_exp = configuration->property(role + ".total_block_exp", 14); acq_parameters.excludelimit = static_cast(std::round(static_cast(fs_in_) / GPS_L2_M_CODE_RATE_CPS)); diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h index 479fb17ae..e9b2fb7e6 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h @@ -151,6 +151,8 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: + const std::string default_device_name = "acquisition_S00_AXI"; // UIO device name + 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 diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc index e2b970888..92808e613 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc @@ -27,6 +27,7 @@ #include "gnss_sdr_flags.h" #include "gnss_sdr_make_unique.h" #include "gps_l5_signal_replica.h" +#include "uio_fpga.h" #include #include // for fft_complex #include // for gr_complex @@ -76,11 +77,19 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( uint32_t nsamples_total = pow(2, nbits); uint32_t select_queue_Fpga = configuration->property(role + ".select_queue_Fpga", 1); acq_parameters.select_queue_Fpga = select_queue_Fpga; - std::string default_device_name = "/dev/uio0"; - std::string device_name = configuration->property(role + ".devicename", default_device_name); - acq_parameters.device_name = device_name; - acq_parameters.samples_per_code = nsamples_total; + // UIO device file + std::string device_io_name; + std::string device_name = configuration->property(role + ".devicename", default_device_name); + // find the uio device file corresponding to the GNSS reset module + if (find_uio_dev_file_name(device_io_name, device_name, 0) < 0) + { + std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl; + throw std::exception(); + } + acq_parameters.device_name = device_io_name; + + acq_parameters.samples_per_code = nsamples_total; acq_parameters.excludelimit = static_cast(1 + ceil((1.0 / GPS_L5I_CODE_RATE_CPS) * static_cast(fs_in))); // compute all the GPS L5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h index 481c40701..19c622b7d 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h @@ -187,6 +187,8 @@ public: private: static const uint32_t NUM_PRNs = 32; + const std::string default_device_name = "acquisition_S00_AXI"; // UIO device name + // 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; diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index c007652cc..1e51a6a43 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -146,6 +146,13 @@ target_include_directories(signal_source_adapters ${CMAKE_SOURCE_DIR}/src/core/interfaces ) +if(ENABLE_FPGA) + target_include_directories(signal_source_adapters + PUBLIC + ${CMAKE_SOURCE_DIR}/src/core/libs + ) +endif() + target_link_libraries(signal_source_adapters PUBLIC Boost::headers diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc index 600176067..7481917fa 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc @@ -28,6 +28,7 @@ #include "ad9361_manager.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" +#include "uio_fpga.h" #include #include #include // for max @@ -90,9 +91,17 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con rf_shutdown_ = configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown); - // turn switch to A/D position - const std::string default_device_name("/dev/uio1"); - const std::string device_name = configuration->property(role + ".devicename", default_device_name); + + // Switch UIO device file + std::string device_io_name; + std::string device_name = configuration->property(role + ".devicename", default_device_name); + // find the uio device file corresponding to the GNSS reset module + if (find_uio_dev_file_name(device_io_name, device_name, 0) < 0) + { + std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl; + throw std::exception(); + } + switch_position = configuration->property(role + ".switch_position", 0); if (switch_position != 0 && switch_position != 2) { @@ -101,7 +110,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con switch_position = 0; } - switch_fpga = std::make_shared(device_name); + switch_fpga = std::make_shared(device_io_name); switch_fpga->set_switch_position(switch_position); item_size_ = sizeof(gr_complex); diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h index f6a594508..e3e84e407 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h @@ -76,6 +76,8 @@ public: gr::basic_block_sptr get_right_block() override; private: + const std::string default_device_name = "AXIS_Switch_v1_0_0"; // Switch UIO device name + // perform dynamic bit selection every 500 ms by default static const uint32_t Gain_control_period_ms = 500; diff --git a/src/algorithms/tracking/adapters/CMakeLists.txt b/src/algorithms/tracking/adapters/CMakeLists.txt index c54a979aa..e991cce28 100644 --- a/src/algorithms/tracking/adapters/CMakeLists.txt +++ b/src/algorithms/tracking/adapters/CMakeLists.txt @@ -109,6 +109,14 @@ target_include_directories(tracking_adapters ${CMAKE_SOURCE_DIR}/src/core/interfaces ) +if(ENABLE_FPGA) + target_include_directories(tracking_adapters + PUBLIC + ${CMAKE_SOURCE_DIR}/src/core/libs + ) +endif() + + if(ENABLE_CUDA) if(CMAKE_VERSION VERSION_GREATER 3.11) target_include_directories(tracking_adapters diff --git a/src/core/libs/CMakeLists.txt b/src/core/libs/CMakeLists.txt index db7ad6f5d..010c92945 100644 --- a/src/core/libs/CMakeLists.txt +++ b/src/core/libs/CMakeLists.txt @@ -36,11 +36,13 @@ if(ENABLE_FPGA) ${CORE_LIBS_SOURCES} gnss_sdr_fpga_sample_counter.cc gnss_sdr_time_counter.cc + uio_fpga.cc ) set(CORE_LIBS_HEADERS ${CORE_LIBS_HEADERS} gnss_sdr_fpga_sample_counter.h gnss_sdr_time_counter.h + uio_fpga.h ) endif() diff --git a/src/core/libs/gnss_sdr_fpga_sample_counter.cc b/src/core/libs/gnss_sdr_fpga_sample_counter.cc index e0752d801..d182060df 100644 --- a/src/core/libs/gnss_sdr_fpga_sample_counter.cc +++ b/src/core/libs/gnss_sdr_fpga_sample_counter.cc @@ -21,6 +21,7 @@ #include "gnss_sdr_fpga_sample_counter.h" #include "gnss_synchro.h" +#include "uio_fpga.h" #include #include #include // for from_double @@ -132,11 +133,20 @@ void gnss_sdr_fpga_sample_counter::configure_samples_per_output(uint32_t interva void gnss_sdr_fpga_sample_counter::open_device() { - // open communication with HW accelerator - if ((fd = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1) + // UIO device file + std::string device_io_name; + // find the uio device file corresponding to the GNSS reset module + if (find_uio_dev_file_name(device_io_name, device_name, 0) < 0) { - LOG(WARNING) << "Cannot open deviceio" << device_name; - std::cout << "Counter-Intr: cannot open deviceio" << device_name << '\n'; + std::cout << "Cannot find the FPGA uio device file corresponding to device name " << device_name << std::endl; + throw std::exception(); + } + + // open communication with HW accelerator + if ((fd = open(device_io_name.c_str(), O_RDWR | O_SYNC)) == -1) + { + LOG(WARNING) << "Cannot open deviceio" << device_io_name; + std::cout << "Counter-Intr: cannot open deviceio" << device_io_name << '\n'; } map_base = reinterpret_cast(mmap(nullptr, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); @@ -144,7 +154,7 @@ void gnss_sdr_fpga_sample_counter::open_device() if (map_base == reinterpret_cast(-1)) { LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory"; - std::cout << "Counter-Intr: cannot map deviceio" << device_name << '\n'; + std::cout << "Counter-Intr: cannot map deviceio" << device_io_name << '\n'; } // sanity check : check test register diff --git a/src/core/libs/gnss_sdr_fpga_sample_counter.h b/src/core/libs/gnss_sdr_fpga_sample_counter.h index fa4b6361f..a59cea1f9 100644 --- a/src/core/libs/gnss_sdr_fpga_sample_counter.h +++ b/src/core/libs/gnss_sdr_fpga_sample_counter.h @@ -50,6 +50,8 @@ public: gr_vector_void_star &output_items); private: + const std::string device_name = "counter"; // UIO device name + 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) @@ -63,8 +65,7 @@ private: bool stop(); void wait_for_interrupt(void); - volatile uint32_t *map_base; // driver memory map - std::string device_name = "/dev/uio2"; // HW device name + volatile uint32_t *map_base; // driver memory map double fs; uint64_t sample_counter; diff --git a/src/core/libs/uio_fpga.cc b/src/core/libs/uio_fpga.cc new file mode 100644 index 000000000..6f33354d0 --- /dev/null +++ b/src/core/libs/uio_fpga.cc @@ -0,0 +1,115 @@ +/*! + * \file uio_fpga.cc + * \brief This library contains functions to determine the uio device driver file that + * corresponds to a hardware accelerator device name in the FPGA + * \author Marc Majoral, 2020. mmajoral(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "uio_fpga.h" +#include // scandir() +#include // ifstream +#include // cout +#include // std::stringstream + +int32_t get_uio_num(std::string uio_name) +{ + size_t i = 0; + // search first digit + for (; i < uio_name.length(); i++) + { + if (isdigit(uio_name[i])) break; + } + + // remove the first chars, which aren't digits + std::string uio_num = uio_name.substr(i, uio_name.length() - i); + + // convert the remaining text to an integer + return atoi(uio_num.c_str()); +} + +void get_uio_name(uint32_t uio_num, std::string &uio_name) +{ + std::stringstream filename; + filename << uio_dir << uio_filename << uio_num << uio_subdir_name; + + std::ifstream infile; + infile.open(filename.str()); + if (infile.is_open()) + { + getline(infile, uio_name); + if (infile.bad()) + { + std::cout << "Could not read the FPGA uio device information file" << std::endl; + throw std::exception(); + } + infile.close(); + } + else + { + std::cout << "Could not open the FPGA uio device information file" << std::endl; + throw std::exception(); + } +} + +int32_t find_uio_num(const std::string &device_name, uint32_t device_num) +{ + struct dirent **files; + int32_t uio_num; + + // get the number of directory entries in the uio driver description system directories + uint32_t num_dir_entries = scandir(uio_dir.c_str(), &files, 0, versionsort); + + uint32_t device_count = 0, uio_count = 0; + + // search for the requested device driver + while (device_count < num_dir_entries) + { + // get the uio number corresponding to directory entry n + uio_num = get_uio_num(files[device_count]->d_name); + if (uio_num >= 0) // valid uio number + { + std::string nametemp; + get_uio_name(uio_num, nametemp); + if (device_name.compare(nametemp) == 0) + { + if (uio_count == device_num) + { + return uio_num; + } + else + { + uio_count++; + } + } + } + device_count++; + } + return -1; // uio number not found +} + +int32_t find_uio_dev_file_name(std::string &device_file_name, const std::string &device_name, uint32_t device_num) +{ + int32_t uio_num = find_uio_num(device_name, device_num); + if (uio_num >= 0) + { + std::stringstream device_file_name_tmp; + device_file_name_tmp << "/dev/uio" << uio_num; + device_file_name = device_file_name_tmp.str(); + return 0; + } + + return -1; +} diff --git a/src/core/libs/uio_fpga.h b/src/core/libs/uio_fpga.h new file mode 100644 index 000000000..addc8b490 --- /dev/null +++ b/src/core/libs/uio_fpga.h @@ -0,0 +1,36 @@ +/*! + * \file uio_fpga.h + * \brief This library contains functions to determine the uio device driver file that + * corresponds to a hardware accelerator device name in the FPGA + * \author Marc Majoral, 2020. mmajoral(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_SIM_GNSS_UIO_FPGA_H +#define GNSS_SDR_SIM_GNSS_UIO_FPGA_H + +#include // string, memset() + +const std::string uio_dir = "/sys/class/uio/"; +const std::string uio_filename = "uio"; +const std::string uio_subdir_name = "/name"; + +/*! + * \brief This function finds the uio device driver device file name out of the device name and the device number + */ +int32_t find_uio_dev_file_name(std::string &device_file_name, const std::string &device_name, uint32_t device_num); + + +#endif // GNSS_SDR_GNSS_UIO_FPGA_H