1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-09-30 07:50:51 +00:00

move all DMA control to Fpga_DMA class

This commit is contained in:
Marc Majoral 2022-04-28 22:33:29 +02:00
parent e740244a63
commit ea172f0d36
3 changed files with 56 additions and 51 deletions

View File

@ -537,10 +537,8 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, cons
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 // FPGA DMA control
dma_fpga = std::make_shared<Fpga_DMA>(); dma_fpga = std::make_shared<Fpga_DMA>();
#endif
// open the files // open the files
try try
@ -602,15 +600,13 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, cons
} }
// 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
// pointer to DMA buffer // pointer to DMA buffer
int8_t *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;
// Open DMA device // Open DMA device
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
if (dma_fpga->DMA_open()) if (dma_fpga->DMA_open())
{ {
std::cerr << "Cannot open loop device\n"; std::cerr << "Cannot open loop device\n";
@ -620,35 +616,6 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, cons
} }
dma_buffer = dma_fpga->get_buffer_address(); dma_buffer = dma_fpga->get_buffer_address();
#else // 32-bit processor architecture
int tx_fd = open("/dev/loop_tx", O_WRONLY);
if (tx_fd < 0)
{
std::cerr << "Cannot open loop device\n";
// stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
return;
}
// note: a problem was identified with the DMA: when switching from tx to rx or rx to tx mode
// the DMA transmission may hang. This problem will be fixed soon.
// for the moment this problem can be avoided by closing and opening the DMA a second time
if (close(tx_fd) < 0)
{
std::cerr << "Error closing loop device " << '\n';
}
// open the DMA a second time
tx_fd = open("/dev/loop_tx", O_WRONLY);
if (tx_fd < 0)
{
std::cerr << "Cannot open loop device\n";
// stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
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)
@ -737,21 +704,11 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, cons
if (nread_elements > 0) if (nread_elements > 0)
{ {
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
if (dma_fpga->DMA_write(nread_elements * 2)) if (dma_fpga->DMA_write(nread_elements * 2))
{ {
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;
} }
#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)
{
std::cerr << "Error: DMA could not send all the required samples\n";
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));
} }
@ -822,17 +779,10 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, cons
lock.unlock(); lock.unlock();
} }
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
if (dma_fpga->DMA_close()) if (dma_fpga->DMA_close())
{ {
std::cerr << "Error closing loop device " << '\n'; std::cerr << "Error closing loop device " << '\n';
} }
#else // 32-bit processor architecture
if (close(tx_fd) < 0)
{
std::cerr << "Error closing loop device " << '\n';
}
#endif
try try
{ {
infile1.close(); infile1.close();

View File

@ -23,6 +23,7 @@
int Fpga_DMA::DMA_open() int Fpga_DMA::DMA_open()
{ {
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
tx_channel.fd = open("/dev/dma_proxy_tx", O_RDWR); tx_channel.fd = open("/dev/dma_proxy_tx", O_RDWR);
if (tx_channel.fd < 1) if (tx_channel.fd < 1)
{ {
@ -38,18 +39,48 @@ int Fpga_DMA::DMA_open()
return -1; return -1;
} }
#else // 32-bit processor architecture
tx_fd = open("/dev/loop_tx", O_WRONLY);
if (tx_fd < 1)
{
return tx_fd;
}
// note: a problem was identified with the DMA: when switching from tx to rx or rx to tx mode
// the DMA transmission may hang. This problem will be fixed soon.
// for the moment this problem can be avoided by closing and opening the DMA a second time
if (close(tx_fd) < 0)
{
std::cerr << "Error closing loop device " << '\n';
return -1;
}
// open the DMA a second time
tx_fd = open("/dev/loop_tx", O_WRONLY);
if (tx_fd < 1)
{
std::cerr << "Cannot open loop device\n";
// stop the receiver
return tx_fd;
}
#endif
return 0; return 0;
} }
int8_t *Fpga_DMA::get_buffer_address(void) int8_t *Fpga_DMA::get_buffer_address(void)
{ {
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
return tx_channel.buf_ptr[0].buffer; return tx_channel.buf_ptr[0].buffer;
#else // 32-bit processor architecture
return buffer;
#endif
} }
int Fpga_DMA::DMA_write(int nbytes) int Fpga_DMA::DMA_write(int nbytes)
{ {
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
int buffer_id = 0; int buffer_id = 0;
tx_channel.buf_ptr[0].length = nbytes; tx_channel.buf_ptr[0].length = nbytes;
@ -73,15 +104,30 @@ int Fpga_DMA::DMA_write(int nbytes)
std::cerr << "Proxy DMA Tx transfer error " << '\n'; std::cerr << "Proxy DMA Tx transfer error " << '\n';
return -1; return -1;
} }
#else // 32-bit processor architecture
const int num_bytes_sent = write(tx_fd, dma_buffer, nread_elements * 2);
if (num_bytes_sent != num_transferred_bytes)
{
return -1
}
#endif
return 0; return 0;
} }
int Fpga_DMA::DMA_close() int Fpga_DMA::DMA_close()
{ {
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
if (munmap(tx_channel.buf_ptr, sizeof(struct channel_buffer))) if (munmap(tx_channel.buf_ptr, sizeof(struct channel_buffer)))
{ {
std::cerr << "Failed to unmap DMA tx channel " << '\n'; std::cerr << "Failed to unmap DMA tx channel " << '\n';
return -1; return -1;
} }
return close(tx_channel.fd); return close(tx_channel.fd);
#else // 32-bit processor architecture
return close(tx_fd);
#endif
} }

View File

@ -22,6 +22,8 @@
#define BUFFER_SIZE (128 * 1024) /* must match driver exactly */ #define BUFFER_SIZE (128 * 1024) /* must match driver exactly */
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
#define TX_BUFFER_COUNT 1 /* app only, must be <= to the number in the driver */ #define TX_BUFFER_COUNT 1 /* app only, must be <= to the number in the driver */
#define FINISH_XFER _IOW('a', 'a', int32_t *) #define FINISH_XFER _IOW('a', 'a', int32_t *)
@ -48,6 +50,8 @@ struct channel
int fd; int fd;
}; };
#endif
/*! /*!
* \brief Class that controls the switch DMA in the FPGA * \brief Class that controls the switch DMA in the FPGA
*/ */
@ -84,6 +88,11 @@ public:
int DMA_close(void); int DMA_close(void);
private: private:
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
channel tx_channel; channel tx_channel;
int8_t buffer[BUFFER_SIZE];
#else // 32-bit processor architecture
int tx_fd;
#endif
}; };
#endif // GNSS_SDR_FPGA_DMA_H #endif // GNSS_SDR_FPGA_DMA_H