04-11-2013 09:00 AM
I have a problem transferring data from the FPGA to the host-PC (using PCI-express) using DMA. Let me first briefly explain what I want to achieve.
I'm working on a project that requires the use of an FPGA (I'm using the XUPV5 board) to observe data coming from the GPIO pins. After some processing, the data is eventually written to a FIFO buffer (rdpfifo_v4_02_a), which is connected to a PLB bus. The FIFO has a depth of 4096 and a width of 32 bits.
The PLB-bus connects the following functional blocks: an XPS Central DMA Controller (2.03a), a PCI-express bridge (plbv46_pcie, 4.07a), and the FIFO spoken of in the text above.
When the FIFO is full, an MSI is successfully generated to let the PC know that data is ready to be transferred. The PC then configures the DMA controller (using a BAR) and initiates a transfer of 16 KB (4x4096). The first block of data is correctly transferred, but the second one generates a DMA Bus Error. The configuration of the DMA Controller is done in exactly the same way as the first one, and I get the first KB of data, then it stops.
It should be noted that, when I make the requested DMA transfer block size smaller, the first block transfers completely, but the second block doesn't. So it's not the FIFO that's empty (I generate an MSI when the FIFO is full, so it contains 4096 32-bit values).
Some additional parameters:
DMA FIFO depth = 48, Rd Burst Size = 8, Wr Burst Size = 8
The PC is running a Linux kernel (3.0.35)
Could it be possible that the DMA Controller in the PC, and the one on the FPGA are fighting for the bus?
If necessary, I'll be glad to give more information.
I really hope someone can point me in the right direction to solve this problem,
04-11-2013 11:39 AM
Okay, so I debugged my design some more, and when I do a DMA transfer from the FIFO buffer to an on-chip BRAM block, I also get a Bus Error after the second DMA transfer.
Has anyone encountered a problem like this before? My interrupt handler (on the PC side) does the following actions:
* The FPGA generates an MSI when the FIFO buffer is full.
* When an interrupt occurs, the DMA controller is initialised by the driver running on the PC: reset it, write source/destination registers, interrupt enable register, length register
* When another interrupt occurs, the driver knows that the DMA transfer is complete (either successfully or unsuccessfully). It sends an Acknowledge signal back to the FPGA, so the latter knows that the driver has knowledge about the DMA completion.
* From here on, the FPGA waits for the FIFO to be full, when it is, an MSI is generated etc etc
I still hope someone can help me out here...