08-19-2020 05:43 AM
I set up an AXI DMA and I changed the Max Transfer length as below:
AxiDma.TxBdRing.MaxTransferLen = IMG_SIZE_BYTES; AxiDma.RxBdRing.MaxTransferLen = IMG_SIZE_BYTES;
Printed out straight after that shows the original value:
xil_printf("DMA TX MAx Transfer Length %i\r\n", AxiDma.TxBdRing.MaxTransferLen); xil_printf("DMA RX MAx Transfer Length %i\r\n", AxiDma.RxBdRing.MaxTransferLen);
But after disabling the DMA interrupts, the lines above show 0. and of course, a DMA transfer fails for the length being greater than the maximum.
To make it even more interesting, I noticed this today while I was working on the same project yesterday without that problem. The changes in between were an HLS IP core that processes the streams from the DMA.
Hopefully, there is an explanation for that.
In the meantime, I'm rebuilding the hardware from scratch.
08-26-2020 12:59 AM
Can you please share a code snippet of disabling the DMA interrupts?
If possible, please provide your DMA application code to have a look on this.
Does rebuilding your hardware from scratch help you to resolve this issue?
08-26-2020 02:47 AM
09-02-2020 01:40 AM
I use the 'standard' instructions from the polling example to disable interrupts:
XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE); XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DEVICE_TO_DMA);
all software is pretty much the polling example.
Yes, I tried rebuilding it from scratch, same behaviour.
09-02-2020 02:00 AM
No, I don't think this can happen. In my application I have an HLS block that processes an image frame and returns a result. both its input and output are AXI-stream and DMA'ed. I first start the S2MM channel to receive the answer, then kick the MM2S channel to stream the frame to it.
It is very puzzling, if I put a plain AXI stream FIFO instead of my processing block, it works, it receives what I send, so I believe there is nothing wrong in the software, but when I replace it with my block it doesn't. Nevertheless both the C simulation and the RTL simulation of that block show there is output data, the only difference is it's only one word at the last input frame word. I do set the Tlast bit as well.
Because in my case, answer (S2MM) is a single word, Tlast should be always high, I thought that could be a problem and tried another version that sends a >1 word answer, but does the same.
Obviously, the number of bytes to receive is set to the right (expected) number (4 for a 32-bit AXI-stream word), different to the number sent (4 x 512 x 640 bytes).
I also tried sending more than one frame and trying to receive just the first answer in case it was held in some buffer somewhere but I caught no answer as well.
09-02-2020 04:19 AM - edited 09-02-2020 04:26 AM
Yes, but that's how it's meant to be, I think. Output is one 32-bit word per frame, Tlast high because it's the first and last data, and the write DMS channel is set to receive 4 bytes, I think that's correct. In theory at least.
I'm not saying I hold Tlast high, what I do is to set, in HLS, Tlast = 1 for the one and only piece of data per frame that comes out. I let HLS to manage that signal as needed between data outputs. I assume there is no problem with Tlast being high all the time as data is marked with Tvalid, but that's just an assumption... I would be surprised if AXI stream frames need to be at least 2 words for Tlast to toggle, but if that were the case I can send a dummy word before.
09-02-2020 05:08 AM
This may well be the problem then.
Xilinx's AXI S2MM core was built for handling Ethernet packet data. It's built to be able to issue a request to move a whole packet of data from point A to point B, and to make the request before the length of the packet is known. This is why the transfer stops if ever the S2MM core sees a TLAST.
If your core has to hold TLAST high, or even toggle it mid-transfer, then you might want to pass the AXI stream through a second core that just sets TLAST low.
09-02-2020 05:30 AM
I just tried a version that should output zero and Tlast =0 for every input word and something else with Tlast = 1 every 64 words in. Nothing.
I manage Tlast in the HLS block output. I'm assuming when I instruct the DMA to send N bytes it sets the Tlast at the end of those N bytes. Completely puzzled...
09-02-2020 07:14 AM
If it helps at all, you could try using some open source AXI MM2S or S2MM DMA's. (There's even video versions for video source and sink) I've hesitated in recommending them at first since they aren't (yet) integrated into Xilinx's IP-XACT IP core framework, still ... they're at least simple and basic (working) RTL. From that standpoint, you should be able to import them, use them, and even investigate what's wrong within them--something you will be struggle to do with Xilinx's IP cores. They're also known for not having the TLAST issues we've been discussing above, nor the issue with sending data prior to when the core is ready. (See the parameter documentation in-line for how to set them up.)
You can find all four of those cores in this repository--along with some other useful AXI cores.