1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-07-05 03:22:56 +00:00
2023-12-21 14:46:27 +01:00

90 lines
2.5 KiB
C++

/*!
* \file fpga_dma-proxy.cc
* \brief FPGA DMA control. This code is based in the Xilinx DMA proxy test application:
* https://github.com/Xilinx-Wiki-Projects/software-prototypes/tree/master/linux-user-space-dma/Software
* \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-proxy.h"
#include <fcntl.h>
#include <iostream> // for std::cerr
#include <sys/ioctl.h> // for ioctl()
#include <sys/mman.h> // libraries used by the GIPO
#include <unistd.h>
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(nullptr, 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;
}
return 0;
}
int8_t *Fpga_DMA::get_buffer_address() // NOLINT(readability-make-member-function-const)
{
return tx_channel.buf_ptr[0].buffer;
}
int Fpga_DMA::DMA_write(int nbytes) const
{
int buffer_id = 0;
tx_channel.buf_ptr[0].length = nbytes;
// start DMA transfer
if (ioctl(tx_channel.fd, _IOW('a', 'b', int32_t *), &buffer_id)) // start transfer
{
std::cerr << "Error starting tx DMA transfer " << '\n';
return -1;
}
// wait for completion of DMA transfer
if (ioctl(tx_channel.fd, _IOW('a', 'a', int32_t *), &buffer_id)) // finish transfer
{
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() const
{
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);
}