mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	added support for the Xilinx dma-proxy driver when using 64-bit processor architectures.
This commit is contained in:
		| @@ -56,6 +56,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con | |||||||
|       gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)), |       gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)), | ||||||
|       rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)), |       rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)), | ||||||
|       filter_filename_(configuration->property(role + ".filter_filename", filter_file_)), |       filter_filename_(configuration->property(role + ".filter_filename", filter_file_)), | ||||||
|  |       filename0_(configuration->property(role + ".filename", empty_string)), | ||||||
|       rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)), |       rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)), | ||||||
|       rf_gain_rx2_(configuration->property(role + ".gain_rx1", default_manual_gain_rx2)), |       rf_gain_rx2_(configuration->property(role + ".gain_rx1", default_manual_gain_rx2)), | ||||||
|       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))), | ||||||
| @@ -109,18 +110,23 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con | |||||||
|     // override value with commandline flag, if present |     // override value with commandline flag, if present | ||||||
|     if (FLAGS_signal_source != "-") |     if (FLAGS_signal_source != "-") | ||||||
|         { |         { | ||||||
|             filename0 = FLAGS_signal_source; |             filename0_ = FLAGS_signal_source; | ||||||
|         } |         } | ||||||
|     if (FLAGS_s != "-") |     if (FLAGS_s != "-") | ||||||
|         { |         { | ||||||
|             filename0 = FLAGS_s; |             filename0_ = FLAGS_s; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |     if (filename0_.empty()) | ||||||
|  |         { | ||||||
|  |             filename0_ = configuration->property(role + ".filename0_", empty_string); | ||||||
|  |             filename1_ = configuration->property(role + ".filename1_", empty_string); | ||||||
|  |         } | ||||||
|     // if only one input file is specified in the configuration file then: |     // if only one input file is specified in the configuration file then: | ||||||
|     // if there is at least one channel assigned to frequency band 1 then the DMA transfers the samples to the L1 frequency band channels |     // if there is at least one channel assigned to frequency band 1 then the DMA transfers the samples to the L1 frequency band channels | ||||||
|     // otherwise the DMA transfers the samples to the L2/L5 frequency band channels |     // otherwise the DMA transfers the samples to the L2/L5 frequency band channels | ||||||
|     // if more than one input file are specified then the DMA transfer the samples to both the L1 and the L2/L5 frequency channels. |     // if more than one input file are specified then the DMA transfer the samples to both the L1 and the L2/L5 frequency channels. | ||||||
|     if (filename1.empty()) |     if (filename1_.empty()) | ||||||
|         { |         { | ||||||
|             num_freq_bands_ = 1; |             num_freq_bands_ = 1; | ||||||
|             if (l1_band != 0) |             if (l1_band != 0) | ||||||
| @@ -172,7 +178,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con | |||||||
|                      * A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the |                      * A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the | ||||||
|                      * valve block |                      * valve block | ||||||
|                      */ |                      */ | ||||||
|                     std::ifstream file(filename0.c_str(), std::ios::in | std::ios::binary | std::ios::ate); |                     std::ifstream file(filename0_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); | ||||||
|                     std::ifstream::pos_type size; |                     std::ifstream::pos_type size; | ||||||
|  |  | ||||||
|                     if (file.is_open()) |                     if (file.is_open()) | ||||||
| @@ -182,13 +188,13 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con | |||||||
|                         } |                         } | ||||||
|                     else |                     else | ||||||
|                         { |                         { | ||||||
|                             std::cerr << "SignalSource: Unable to open the samples file " << filename0.c_str() << '\n'; |                             std::cerr << "SignalSource: Unable to open the samples file " << filename0_.c_str() << '\n'; | ||||||
|                             item_size_ = 0; |                             item_size_ = 0; | ||||||
|                             return; |                             return; | ||||||
|                         } |                         } | ||||||
|                     std::streamsize ss = std::cout.precision(); |                     std::streamsize ss = std::cout.precision(); | ||||||
|                     std::cout << std::setprecision(16); |                     std::cout << std::setprecision(16); | ||||||
|                     std::cout << "Processing file " << filename0 << ", which contains " << static_cast<double>(size) << " [bytes]\n"; |                     std::cout << "Processing file " << filename0_ << ", which contains " << static_cast<double>(size) << " [bytes]\n"; | ||||||
|                     std::cout.precision(ss); |                     std::cout.precision(ss); | ||||||
|  |  | ||||||
|                     if (size > 0) |                     if (size > 0) | ||||||
| @@ -198,9 +204,9 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con | |||||||
|                             samples_ = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size_) - ceil(0.002 * static_cast<double>(sample_rate_)));  // process all the samples available in the file excluding at least the last 1 ms |                             samples_ = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size_) - ceil(0.002 * static_cast<double>(sample_rate_)));  // process all the samples available in the file excluding at least the last 1 ms | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                     if (!filename1.empty()) |                     if (!filename1_.empty()) | ||||||
|                         { |                         { | ||||||
|                             std::ifstream file(filename1.c_str(), std::ios::in | std::ios::binary | std::ios::ate); |                             std::ifstream file(filename1_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); | ||||||
|                             std::ifstream::pos_type size; |                             std::ifstream::pos_type size; | ||||||
|  |  | ||||||
|                             if (file.is_open()) |                             if (file.is_open()) | ||||||
| @@ -210,13 +216,13 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con | |||||||
|                                 } |                                 } | ||||||
|                             else |                             else | ||||||
|                                 { |                                 { | ||||||
|                                     std::cerr << "SignalSource: Unable to open the samples file " << filename1.c_str() << '\n'; |                                     std::cerr << "SignalSource: Unable to open the samples file " << filename1_.c_str() << '\n'; | ||||||
|                                     item_size_ = 0; |                                     item_size_ = 0; | ||||||
|                                     return; |                                     return; | ||||||
|                                 } |                                 } | ||||||
|                             std::streamsize ss = std::cout.precision(); |                             std::streamsize ss = std::cout.precision(); | ||||||
|                             std::cout << std::setprecision(16); |                             std::cout << std::setprecision(16); | ||||||
|                             std::cout << "Processing file " << filename1 << ", which contains " << static_cast<double>(size) << " [bytes]\n"; |                             std::cout << "Processing file " << filename1_ << ", which contains " << static_cast<double>(size) << " [bytes]\n"; | ||||||
|                             std::cout.precision(ss); |                             std::cout.precision(ss); | ||||||
|  |  | ||||||
|                             int64_t samples_rx2 = 0; |                             int64_t samples_rx2 = 0; | ||||||
| @@ -236,14 +242,14 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con | |||||||
|             DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; |             DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; | ||||||
|             std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n"; |             std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n"; | ||||||
|  |  | ||||||
|             if (filename1.empty()) |             if (filename1_.empty()) | ||||||
|                 { |                 { | ||||||
|                     DLOG(INFO) << "File source filename " << filename0; |                     DLOG(INFO) << "File source filename " << filename0_; | ||||||
|                 } |                 } | ||||||
|             else |             else | ||||||
|                 { |                 { | ||||||
|                     DLOG(INFO) << "File source filename rx1 " << filename0; |                     DLOG(INFO) << "File source filename rx1 " << filename0_; | ||||||
|                     DLOG(INFO) << "File source filename rx2 " << filename1; |                     DLOG(INFO) << "File source filename rx2 " << filename1_; | ||||||
|                 } |                 } | ||||||
|             DLOG(INFO) << "Samples " << samples_; |             DLOG(INFO) << "Samples " << samples_; | ||||||
|             DLOG(INFO) << "Sampling frequency " << sample_rate_; |             DLOG(INFO) << "Sampling frequency " << sample_rate_; | ||||||
| @@ -521,39 +527,45 @@ Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource() | |||||||
|  |  | ||||||
| void Ad9361FpgaSignalSource::start() | void Ad9361FpgaSignalSource::start() | ||||||
| { | { | ||||||
|     thread_file_to_dma = std::thread([&] { run_DMA_process(filename0, filename1, samples_to_skip_, item_size_, samples_, repeat_, dma_buff_offset_pos_, queue_); }); |     thread_file_to_dma = std::thread([&] { run_DMA_process(filename0_, filename1_, samples_to_skip_, item_size_, samples_, repeat_, dma_buff_offset_pos_, queue_); }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const std::string &filename1, uint64_t &samples_to_skip, size_t &item_size, int64_t &samples, bool &repeat, uint32_t &dma_buff_offset_pos, Concurrent_Queue<pmt::pmt_t> *queue) | void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, const std::string &filename1_, uint64_t &samples_to_skip, size_t &item_size, int64_t &samples, bool &repeat, uint32_t &dma_buff_offset_pos, Concurrent_Queue<pmt::pmt_t> *queue) | ||||||
| { | { | ||||||
|     std::ifstream infile1; |     std::ifstream infile1; | ||||||
|     infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit); |     infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #if INTPTR_MAX == INT64_MAX  // 64-bit processor architecture | ||||||
|  |     // FPGA DMA control | ||||||
|  |     dma_fpga = std::make_shared<Fpga_DMA>(); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     // open the files |     // open the files | ||||||
|     try |     try | ||||||
|         { |         { | ||||||
|             infile1.open(filename0, std::ios::binary); |             infile1.open(filename0_, std::ios::binary); | ||||||
|         } |         } | ||||||
|     catch (const std::ifstream::failure &e) |     catch (const std::ifstream::failure &e) | ||||||
|         { |         { | ||||||
|             std::cerr << "Exception opening file " << filename0 << '\n'; |             std::cerr << "Exception opening file " << filename0_ << '\n'; | ||||||
|             // stop the receiver |             // stop the receiver | ||||||
|             queue->push(pmt::make_any(command_event_make(200, 0))); |             queue->push(pmt::make_any(command_event_make(200, 0))); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     std::ifstream infile2; |     std::ifstream infile2; | ||||||
|     if (!filename1.empty()) |     if (!filename1_.empty()) | ||||||
|         { |         { | ||||||
|             infile2.exceptions(std::ifstream::failbit | std::ifstream::badbit); |             infile2.exceptions(std::ifstream::failbit | std::ifstream::badbit); | ||||||
|             try |             try | ||||||
|                 { |                 { | ||||||
|                     infile2.open(filename1, std::ios::binary); |                     infile2.open(filename1_, std::ios::binary); | ||||||
|                 } |                 } | ||||||
|             catch (const std::ifstream::failure &e) |             catch (const std::ifstream::failure &e) | ||||||
|                 { |                 { | ||||||
|                     std::cerr << "Exception opening file " << filename1 << '\n'; |                     std::cerr << "Exception opening file " << filename1_ << '\n'; | ||||||
|                     // stop the receiver |                     // stop the receiver | ||||||
|                     queue->push(pmt::make_any(command_event_make(200, 0))); |                     queue->push(pmt::make_any(command_event_make(200, 0))); | ||||||
|                     return; |                     return; | ||||||
| @@ -568,13 +580,13 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|         } |         } | ||||||
|     catch (const std::ifstream::failure &e) |     catch (const std::ifstream::failure &e) | ||||||
|         { |         { | ||||||
|             std::cerr << "Exception skipping initial samples file " << filename0 << '\n'; |             std::cerr << "Exception skipping initial samples file " << filename0_ << '\n'; | ||||||
|             // stop the receiver |             // stop the receiver | ||||||
|             queue->push(pmt::make_any(command_event_make(200, 0))); |             queue->push(pmt::make_any(command_event_make(200, 0))); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     if (!filename1.empty()) |     if (!filename1_.empty()) | ||||||
|         { |         { | ||||||
|             try |             try | ||||||
|                 { |                 { | ||||||
| @@ -582,7 +594,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|                 } |                 } | ||||||
|             catch (const std::ifstream::failure &e) |             catch (const std::ifstream::failure &e) | ||||||
|                 { |                 { | ||||||
|                     std::cerr << "Exception skipping initial samples file " << filename1 << '\n'; |                     std::cerr << "Exception skipping initial samples file " << filename1_ << '\n'; | ||||||
|                     // stop the receiver |                     // stop the receiver | ||||||
|                     queue->push(pmt::make_any(command_event_make(200, 0))); |                     queue->push(pmt::make_any(command_event_make(200, 0))); | ||||||
|                     return; |                     return; | ||||||
| @@ -592,12 +604,23 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|     // rx signal vectors |     // rx signal vectors | ||||||
|     std::vector<int8_t> input_samples(sample_block_size * 2);      // complex samples |     std::vector<int8_t> input_samples(sample_block_size * 2);      // complex samples | ||||||
|     std::vector<int8_t> input_samples_dma(sample_block_size * 4);  // complex samples, two frequency bands |     std::vector<int8_t> input_samples_dma(sample_block_size * 4);  // complex samples, two frequency bands | ||||||
|  |     // pointer to DMA buffer | ||||||
|  |     int8_t *dma_buffer; | ||||||
|     int nread_elements = 0;  // num bytes read from the file corresponding to frequency band 1 |     int nread_elements = 0;  // num bytes read from the file corresponding to frequency band 1 | ||||||
|     bool run_DMA = true; |     bool run_DMA = true; | ||||||
|     int num_transferred_bytes; |  | ||||||
|  |  | ||||||
|     // Open DMA device |     // Open DMA device | ||||||
|  | #if INTPTR_MAX == INT64_MAX  // 64-bit processor architecture | ||||||
|  |     if (dma_fpga->DMA_open()) | ||||||
|  |         { | ||||||
|  |             std::cerr << "Cannot open loop device\n"; | ||||||
|  |             // stop the receiver | ||||||
|  |             queue->push(pmt::make_any(command_event_make(200, 0))); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |     dma_buffer = dma_fpga->get_buffer_address(); | ||||||
|  |  | ||||||
|  | #else  // 32-bit processor architecture | ||||||
|     int tx_fd = open("/dev/loop_tx", O_WRONLY); |     int tx_fd = open("/dev/loop_tx", O_WRONLY); | ||||||
|     if (tx_fd < 0) |     if (tx_fd < 0) | ||||||
|         { |         { | ||||||
| @@ -623,6 +646,9 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |     dma_buffer = input_samples_dma; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     // if only one frequency band is used then clear the samples corresponding to the unused frequency band |     // if only one frequency band is used then clear the samples corresponding to the unused frequency band | ||||||
|     uint32_t dma_index = 0; |     uint32_t dma_index = 0; | ||||||
|     if (num_freq_bands_ == 1) |     if (num_freq_bands_ == 1) | ||||||
| @@ -630,8 +656,8 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|             // if only one file is enabled then clear the samples corresponding to the frequency band that is not used. |             // if only one file is enabled then clear the samples corresponding to the frequency band that is not used. | ||||||
|             for (int index0 = 0; index0 < (nread_elements); index0 += 2) |             for (int index0 = 0; index0 < (nread_elements); index0 += 2) | ||||||
|                 { |                 { | ||||||
|                     input_samples_dma[dma_index + (2 - dma_buff_offset_pos)] = 0; |                     dma_buffer[dma_index + (2 - dma_buff_offset_pos)] = 0; | ||||||
|                     input_samples_dma[dma_index + 1 + (2 - dma_buff_offset_pos)] = 0; |                     dma_buffer[dma_index + 1 + (2 - dma_buff_offset_pos)] = 0; | ||||||
|                     dma_index += 4; |                     dma_index += 4; | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
| @@ -656,7 +682,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|                 } |                 } | ||||||
|             catch (const std::ifstream::failure &e) |             catch (const std::ifstream::failure &e) | ||||||
|                 { |                 { | ||||||
|                     std::cerr << "Exception reading file " << filename0 << '\n'; |                     std::cerr << "Exception reading file " << filename0_ << '\n'; | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|             if (infile1) |             if (infile1) | ||||||
| @@ -672,8 +698,8 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|             for (int index0 = 0; index0 < (nread_elements); index0 += 2) |             for (int index0 = 0; index0 < (nread_elements); index0 += 2) | ||||||
|                 { |                 { | ||||||
|                     // dma_buff_offset_pos is 1 for the L1 band and 0 for the other bands |                     // dma_buff_offset_pos is 1 for the L1 band and 0 for the other bands | ||||||
|                     input_samples_dma[dma_index + dma_buff_offset_pos] = input_samples[index0]; |                     dma_buffer[dma_index + dma_buff_offset_pos] = input_samples[index0]; | ||||||
|                     input_samples_dma[dma_index + 1 + dma_buff_offset_pos] = input_samples[index0 + 1]; |                     dma_buffer[dma_index + 1 + dma_buff_offset_pos] = input_samples[index0 + 1]; | ||||||
|                     dma_index += 4; |                     dma_index += 4; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -687,7 +713,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|                         } |                         } | ||||||
|                     catch (const std::ifstream::failure &e) |                     catch (const std::ifstream::failure &e) | ||||||
|                         { |                         { | ||||||
|                             std::cerr << "Exception reading file " << filename1 << '\n'; |                             std::cerr << "Exception reading file " << filename1_ << '\n'; | ||||||
|                             break; |                             break; | ||||||
|                         } |                         } | ||||||
|                     if (infile2) |                     if (infile2) | ||||||
| @@ -703,22 +729,29 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|                     for (int index0 = 0; index0 < (nread_elements); index0 += 2) |                     for (int index0 = 0; index0 < (nread_elements); index0 += 2) | ||||||
|                         { |                         { | ||||||
|                             // filename2 is never the L1 band |                             // filename2 is never the L1 band | ||||||
|                             input_samples_dma[dma_index] = input_samples[index0]; |                             dma_buffer[dma_index] = input_samples[index0]; | ||||||
|                             input_samples_dma[dma_index + 1] = input_samples[index0 + 1]; |                             dma_buffer[dma_index + 1] = input_samples[index0 + 1]; | ||||||
|                             dma_index += 4; |                             dma_index += 4; | ||||||
|                         } |                         } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|             if (nread_elements > 0) |             if (nread_elements > 0) | ||||||
|                 { |                 { | ||||||
|                     num_transferred_bytes = nread_elements * 2; | #if INTPTR_MAX == INT64_MAX  // 64-bit processor architecture | ||||||
|                     const int num_bytes_sent = write(tx_fd, input_samples_dma.data(), nread_elements * 2); |                     if (dma_fpga->DMA_write(nread_elements * 2)) | ||||||
|  |                         { | ||||||
|  |                             std::cerr << "Error: DMA could not send all the required samples\n"; | ||||||
|  |                             break; | ||||||
|  |                         } | ||||||
|  | #else  // 32-bit processor architecture | ||||||
|  |                     int num_transferred_bytes = nread_elements * 2; | ||||||
|  |                     const int num_bytes_sent = write(tx_fd, dma_buffer, nread_elements * 2); | ||||||
|                     if (num_bytes_sent != num_transferred_bytes) |                     if (num_bytes_sent != num_transferred_bytes) | ||||||
|                         { |                         { | ||||||
|                             std::cerr << "Error: DMA could not send all the required samples\n"; |                             std::cerr << "Error: DMA could not send all the required samples\n"; | ||||||
|                             break; |                             break; | ||||||
|                         } |                         } | ||||||
|  | #endif | ||||||
|                     // Throttle the DMA |                     // Throttle the DMA | ||||||
|                     std::this_thread::sleep_for(std::chrono::milliseconds(1)); |                     std::this_thread::sleep_for(std::chrono::milliseconds(1)); | ||||||
|                 } |                 } | ||||||
| @@ -736,7 +769,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|                                 } |                                 } | ||||||
|                             catch (const std::ifstream::failure &e) |                             catch (const std::ifstream::failure &e) | ||||||
|                                 { |                                 { | ||||||
|                                     std::cerr << "Exception resetting the position of the next byte to be extracted to zero " << filename0 << '\n'; |                                     std::cerr << "Exception resetting the position of the next byte to be extracted to zero " << filename0_ << '\n'; | ||||||
|                                     break; |                                     break; | ||||||
|                                 } |                                 } | ||||||
|  |  | ||||||
| @@ -748,11 +781,11 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|                                 } |                                 } | ||||||
|                             catch (const std::ifstream::failure &e) |                             catch (const std::ifstream::failure &e) | ||||||
|                                 { |                                 { | ||||||
|                                     std::cerr << "Exception skipping initial samples file " << filename0 << '\n'; |                                     std::cerr << "Exception skipping initial samples file " << filename0_ << '\n'; | ||||||
|                                     break; |                                     break; | ||||||
|                                 } |                                 } | ||||||
|  |  | ||||||
|                             if (!filename1.empty()) |                             if (!filename1_.empty()) | ||||||
|                                 { |                                 { | ||||||
|                                     try |                                     try | ||||||
|                                         { |                                         { | ||||||
| @@ -760,7 +793,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|                                         } |                                         } | ||||||
|                                     catch (const std::ifstream::failure &e) |                                     catch (const std::ifstream::failure &e) | ||||||
|                                         { |                                         { | ||||||
|                                             std::cerr << "Exception setting the position of the next byte to be extracted to zero " << filename1 << '\n'; |                                             std::cerr << "Exception setting the position of the next byte to be extracted to zero " << filename1_ << '\n'; | ||||||
|                                             break; |                                             break; | ||||||
|                                         } |                                         } | ||||||
|  |  | ||||||
| @@ -770,7 +803,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|                                         } |                                         } | ||||||
|                                     catch (const std::ifstream::failure &e) |                                     catch (const std::ifstream::failure &e) | ||||||
|                                         { |                                         { | ||||||
|                                             std::cerr << "Exception skipping initial samples file " << filename1 << '\n'; |                                             std::cerr << "Exception skipping initial samples file " << filename1_ << '\n'; | ||||||
|                                             break; |                                             break; | ||||||
|                                         } |                                         } | ||||||
|                                 } |                                 } | ||||||
| @@ -789,18 +822,24 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|             lock.unlock(); |             lock.unlock(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | #if INTPTR_MAX == INT64_MAX  // 64-bit processor architecture | ||||||
|  |     if (dma_fpga->DMA_close()) | ||||||
|  |         { | ||||||
|  |             std::cerr << "Error closing loop device " << '\n'; | ||||||
|  |         } | ||||||
|  | #else  // 32-bit processor architecture | ||||||
|     if (close(tx_fd) < 0) |     if (close(tx_fd) < 0) | ||||||
|         { |         { | ||||||
|             std::cerr << "Error closing loop device " << '\n'; |             std::cerr << "Error closing loop device " << '\n'; | ||||||
|         } |         } | ||||||
|  | #endif | ||||||
|     try |     try | ||||||
|         { |         { | ||||||
|             infile1.close(); |             infile1.close(); | ||||||
|         } |         } | ||||||
|     catch (const std::ifstream::failure &e) |     catch (const std::ifstream::failure &e) | ||||||
|         { |         { | ||||||
|             std::cerr << "Exception closing file " << filename0 << '\n'; |             std::cerr << "Exception closing file " << filename0_ << '\n'; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     if (num_freq_bands_ > 1) |     if (num_freq_bands_ > 1) | ||||||
| @@ -811,7 +850,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const | |||||||
|                 } |                 } | ||||||
|             catch (const std::ifstream::failure &e) |             catch (const std::ifstream::failure &e) | ||||||
|                 { |                 { | ||||||
|                     std::cerr << "Exception closing file " << filename1 << '\n'; |                     std::cerr << "Exception closing file " << filename1_ << '\n'; | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,6 +23,9 @@ | |||||||
|  |  | ||||||
| #include "concurrent_queue.h" | #include "concurrent_queue.h" | ||||||
| #include "fpga_buffer_monitor.h" | #include "fpga_buffer_monitor.h" | ||||||
|  | #if INTPTR_MAX == INT64_MAX  // 64-bit processor architecture | ||||||
|  | #include "fpga_dma.h" | ||||||
|  | #endif | ||||||
| #include "fpga_dynamic_bit_selection.h" | #include "fpga_dynamic_bit_selection.h" | ||||||
| #include "fpga_switch.h" | #include "fpga_switch.h" | ||||||
| #include "gnss_block_interface.h" | #include "gnss_block_interface.h" | ||||||
| @@ -71,6 +74,7 @@ private: | |||||||
|     const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat"); |     const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat"); | ||||||
|     const std::string default_rf_port_select = std::string("A_BALANCED"); |     const std::string default_rf_port_select = std::string("A_BALANCED"); | ||||||
|     const std::string default_gain_mode = std::string("slow_attack"); |     const std::string default_gain_mode = std::string("slow_attack"); | ||||||
|  |     const std::string empty_string; | ||||||
|     const double default_tx_attenuation_db = -10.0; |     const double default_tx_attenuation_db = -10.0; | ||||||
|     const double default_manual_gain_rx1 = 64.0; |     const double default_manual_gain_rx1 = 64.0; | ||||||
|     const double default_manual_gain_rx2 = 64.0; |     const double default_manual_gain_rx2 = 64.0; | ||||||
| @@ -105,6 +109,10 @@ private: | |||||||
|     std::shared_ptr<Fpga_dynamic_bit_selection> dynamic_bit_selection_fpga; |     std::shared_ptr<Fpga_dynamic_bit_selection> dynamic_bit_selection_fpga; | ||||||
|     std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga; |     std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga; | ||||||
|  |  | ||||||
|  | #if INTPTR_MAX == INT64_MAX  // 64-bit processor architecture | ||||||
|  |     std::shared_ptr<Fpga_DMA> dma_fpga; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     std::mutex dma_mutex; |     std::mutex dma_mutex; | ||||||
|     std::mutex dynamic_bit_selection_mutex; |     std::mutex dynamic_bit_selection_mutex; | ||||||
|     std::mutex buffer_monitor_mutex; |     std::mutex buffer_monitor_mutex; | ||||||
| @@ -118,8 +126,8 @@ private: | |||||||
|     std::string filter_file_; |     std::string filter_file_; | ||||||
|     std::string filter_source_; |     std::string filter_source_; | ||||||
|     std::string filter_filename_; |     std::string filter_filename_; | ||||||
|     std::string filename0; |     std::string filename0_; | ||||||
|     std::string filename1; |     std::string filename1_; | ||||||
|  |  | ||||||
|     double rf_gain_rx1_; |     double rf_gain_rx1_; | ||||||
|     double rf_gain_rx2_; |     double rf_gain_rx2_; | ||||||
|   | |||||||
| @@ -19,6 +19,8 @@ if(ENABLE_FPGA OR ENABLE_AD9361) | |||||||
|     set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dynamic_bit_selection.h) |     set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dynamic_bit_selection.h) | ||||||
|     set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc) |     set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc) | ||||||
|     set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h) |     set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h) | ||||||
|  |     set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dma.cc) | ||||||
|  |     set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dma.h)     | ||||||
| endif() | endif() | ||||||
|  |  | ||||||
| set(SIGNAL_SOURCE_LIB_SOURCES | set(SIGNAL_SOURCE_LIB_SOURCES | ||||||
|   | |||||||
							
								
								
									
										116
									
								
								src/algorithms/signal_source/libs/fpga_dma.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/algorithms/signal_source/libs/fpga_dma.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | |||||||
|  | /*! | ||||||
|  |  * \file fpga_dma.cc | ||||||
|  |  * \brief FPGA DMA control. | ||||||
|  |  * \author Marc Majoral, mmajoral(at)cttc.es | ||||||
|  |  * | ||||||
|  |  * ----------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2022  (see AUTHORS file for a list of contributors) | ||||||
|  |  * SPDX-License-Identifier: GPL-3.0-or-later | ||||||
|  |  * | ||||||
|  |  * ----------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "fpga_dma.h" | ||||||
|  | #include <errno.h> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <iostream>  // for operator<< | ||||||
|  | #include <pthread.h> | ||||||
|  | #include <sched.h> | ||||||
|  | #include <signal.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <sys/ioctl.h> | ||||||
|  | #include <sys/mman.h> | ||||||
|  | #include <sys/param.h> | ||||||
|  | #include <sys/time.h> | ||||||
|  | #include <time.h> | ||||||
|  | #include <unistd.h> | ||||||
|  |  | ||||||
|  | //Fpga_DMA::Fpga_DMA() | ||||||
|  | //{ | ||||||
|  | // | ||||||
|  | //} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int Fpga_DMA::DMA_open() | ||||||
|  | { | ||||||
|  |     tx_channel.fd = open("/dev/dma_proxy_tx", O_RDWR); | ||||||
|  |     if (tx_channel.fd < 1) | ||||||
|  |         { | ||||||
|  |             return tx_channel.fd; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     tx_channel.buf_ptr = (struct channel_buffer *)mmap(NULL, sizeof(struct channel_buffer) * TX_BUFFER_COUNT, | ||||||
|  |         PROT_READ | PROT_WRITE, MAP_SHARED, tx_channel.fd, 0); | ||||||
|  |     if (tx_channel.buf_ptr == MAP_FAILED) | ||||||
|  |         { | ||||||
|  |             std::cerr << "Failed to mmap DMA tx channel\n" | ||||||
|  |                       << std::endl; | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     //buffer = std::vector<int8_t>(BUFFER_SIZE); | ||||||
|  |     //tx_channel.buf_ptr[0].buffer2 = buffer; | ||||||
|  |     //tx_channel.buf_ptr[0].buffer = &buffer; | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int8_t *Fpga_DMA::get_buffer_address(void) | ||||||
|  | { | ||||||
|  |     return tx_channel.buf_ptr[0].buffer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int Fpga_DMA::DMA_write(int nbytes) | ||||||
|  | { | ||||||
|  |     int buffer_id = 0; | ||||||
|  |  | ||||||
|  |     tx_channel.buf_ptr[0].length = nbytes; | ||||||
|  |     //std::cout << "transmitting " << nbytes << " bytes" << std::endl; | ||||||
|  |  | ||||||
|  |     // debug write values to buffer | ||||||
|  |     //for (uint k= 0; k < 512; k++) | ||||||
|  |     //{ | ||||||
|  |     //	tx_channel.buf_ptr[0].buffer[k] = k; | ||||||
|  |     //} | ||||||
|  |  | ||||||
|  |     // start DMA transfer | ||||||
|  |     if (ioctl(tx_channel.fd, START_XFER, &buffer_id)) | ||||||
|  |         { | ||||||
|  |             std::cerr << "Error starting tx DMA transfer " << '\n'; | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     // wait for completion of DMA transfer | ||||||
|  |     if (ioctl(tx_channel.fd, FINISH_XFER, &buffer_id)) | ||||||
|  |         { | ||||||
|  |             std::cerr << "Error detecting end of DMA transfer " << '\n'; | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     if (tx_channel.buf_ptr[buffer_id].status) | ||||||
|  |         { | ||||||
|  |             std::cerr << "Proxy DMA Tx transfer error " << '\n'; | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Fpga_DMA::DMA_close() | ||||||
|  | { | ||||||
|  |     if (munmap(tx_channel.buf_ptr, sizeof(struct channel_buffer))) | ||||||
|  |         { | ||||||
|  |             std::cerr << "Failed to unmap DMA tx channel " << '\n'; | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
|  |     return close(tx_channel.fd); | ||||||
|  | } | ||||||
							
								
								
									
										95
									
								
								src/algorithms/signal_source/libs/fpga_dma.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/algorithms/signal_source/libs/fpga_dma.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | |||||||
|  | /*! | ||||||
|  |  * \file fpga_dma.h | ||||||
|  |  * \brief FPGA DMA control. | ||||||
|  |  * \author Marc Majoral, mmajoral(at)cttc.es | ||||||
|  |  * | ||||||
|  |  * ----------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2022  (see AUTHORS file for a list of contributors) | ||||||
|  |  * SPDX-License-Identifier: GPL-3.0-or-later | ||||||
|  |  * | ||||||
|  |  * ----------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifndef GNSS_SDR_FPGA_DMA_H | ||||||
|  | #define GNSS_SDR_FPGA_DMA_H | ||||||
|  |  | ||||||
|  | #include <cstdint> | ||||||
|  | #include <vector> | ||||||
|  |  | ||||||
|  | #define BUFFER_SIZE (128 * 1024) /* must match driver exactly */ | ||||||
|  |  | ||||||
|  | #define TX_BUFFER_COUNT 1 /* app only, must be <= to the number in the driver */ | ||||||
|  |  | ||||||
|  | #define FINISH_XFER _IOW('a', 'a', int32_t *) | ||||||
|  | #define START_XFER _IOW('a', 'b', int32_t *) | ||||||
|  |  | ||||||
|  | // channel buffer structure | ||||||
|  | struct channel_buffer | ||||||
|  | { | ||||||
|  |     //unsigned int buffer[BUFFER_SIZE / sizeof(unsigned int)]; | ||||||
|  |     int8_t buffer[BUFFER_SIZE]; | ||||||
|  |     //int8_t *buffer2; | ||||||
|  |     //std::vector<int8_t> * buffer; | ||||||
|  |     enum proxy_status | ||||||
|  |     { | ||||||
|  |         PROXY_NO_ERROR = 0, | ||||||
|  |         PROXY_BUSY = 1, | ||||||
|  |         PROXY_TIMEOUT = 2, | ||||||
|  |         PROXY_ERROR = 3 | ||||||
|  |     } status; | ||||||
|  |     unsigned int length; | ||||||
|  | } __attribute__((aligned(1024))); /* 64 byte alignment required for DMA, but 1024 handy for viewing memory */ | ||||||
|  |  | ||||||
|  | // internal DMA channel data structure | ||||||
|  | struct channel | ||||||
|  | { | ||||||
|  |     struct channel_buffer *buf_ptr; | ||||||
|  |     int fd; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief Class that controls the switch DMA in the FPGA | ||||||
|  |  */ | ||||||
|  | class Fpga_DMA | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     /*! | ||||||
|  |      * \brief Default constructor. | ||||||
|  |      */ | ||||||
|  |     Fpga_DMA() = default; | ||||||
|  |  | ||||||
|  |     /*! | ||||||
|  |      * \brief Default destructor. | ||||||
|  |      */ | ||||||
|  |     ~Fpga_DMA() = default; | ||||||
|  |  | ||||||
|  |     /*! | ||||||
|  |      * \brief Open the DMA device driver. | ||||||
|  |      */ | ||||||
|  |     int DMA_open(void); | ||||||
|  |  | ||||||
|  |     /*! | ||||||
|  |      * \brief Obtain DMA buffer address. | ||||||
|  |      */ | ||||||
|  |     int8_t *get_buffer_address(void); | ||||||
|  |     /*! | ||||||
|  |      * \brief Transfer DMA data | ||||||
|  |      */ | ||||||
|  |     int DMA_write(int nbytes); | ||||||
|  |  | ||||||
|  |     /*! | ||||||
|  |      * \brief Close the DMA device driver | ||||||
|  |      */ | ||||||
|  |     int DMA_close(void); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     channel tx_channel; | ||||||
|  |     //int8_t buffer[BUFFER_SIZE]; | ||||||
|  |     //std::vector<int8_t> buffer; | ||||||
|  | }; | ||||||
|  | #endif  // GNSS_SDR_FPGA_DMA_H | ||||||
		Reference in New Issue
	
	Block a user
	 Marc Majoral
					Marc Majoral