1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-06-29 08:23:19 +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);
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
// FPGA DMA control
dma_fpga = std::make_shared<Fpga_DMA>();
#endif
// open the files
try
@ -602,15 +600,13 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, cons
}
// rx signal vectors
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(sample_block_size * 2); // complex samples
// pointer to DMA buffer
int8_t *dma_buffer;
int nread_elements = 0; // num bytes read from the file corresponding to frequency band 1
bool run_DMA = true;
// Open DMA device
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
if (dma_fpga->DMA_open())
{
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();
#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
uint32_t dma_index = 0;
if (num_freq_bands_ == 1)
@ -737,21 +704,11 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, cons
if (nread_elements > 0)
{
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
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)
{
std::cerr << "Error: DMA could not send all the required samples\n";
break;
}
#endif
// Throttle the DMA
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();
}
#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)
{
std::cerr << "Error closing loop device " << '\n';
}
#endif
try
{
infile1.close();

View File

@ -23,6 +23,7 @@
int Fpga_DMA::DMA_open()
{
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
tx_channel.fd = open("/dev/dma_proxy_tx", O_RDWR);
if (tx_channel.fd < 1)
{
@ -38,18 +39,48 @@ int Fpga_DMA::DMA_open()
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;
}
int8_t *Fpga_DMA::get_buffer_address(void)
{
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
return tx_channel.buf_ptr[0].buffer;
#else // 32-bit processor architecture
return buffer;
#endif
}
int Fpga_DMA::DMA_write(int nbytes)
{
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
int buffer_id = 0;
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';
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;
}
int Fpga_DMA::DMA_close()
{
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
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);
#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 */
#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 FINISH_XFER _IOW('a', 'a', int32_t *)
@ -48,6 +50,8 @@ struct channel
int fd;
};
#endif
/*!
* \brief Class that controls the switch DMA in the FPGA
*/
@ -84,6 +88,11 @@ public:
int DMA_close(void);
private:
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
channel tx_channel;
int8_t buffer[BUFFER_SIZE];
#else // 32-bit processor architecture
int tx_fd;
#endif
};
#endif // GNSS_SDR_FPGA_DMA_H