I have been trying for days to get the AXI DMA IP core to run in cyclic bd mode with PYNQ. I have followed the programming sequence from the product guide (PG021). I only want to use the S2MM channel. So I created a buffer with pynq.allocate() and an array of descriptors, with the last descriptor pointing back to the first. Then I used the programming sequence from scatter/gather mode:
A DMA operation for the S2MM channel is set up and started by using the following sequence:
Write the address of the starting descriptor to the Current Descriptor register. If AXI DMA is configured for an address space greater than 32, then also program the MSB 32 bits of the current descriptor.
Start the S2MM channel running by setting the run/stop bit to 1 (S2MM_DMACR.RS =1).
The halted bit (DMASR.Halted) should deassert indicating the S2MM channel is running.
If desired, enable interrupts by writing a 1 to S2MM_DMACR.IOC_IrqEn and S2MM_DMACR.Err_IrqEn.
Write a valid address to the Tail Descriptor register. If AXI DMA is configured for an address space greater than 32, then also program the MSB 32 bits of the current descriptor.
Writing to the Tail Descriptor register triggers the DMA to start fetching the descriptors from the memory. The fetched descriptors are processed and any data received from the S2MM streaming channel is written to the memory.
The only thing that needs to be changed then is that the cyclic bit in the control register must be set and the tail descriptor register must be written with a value that is not part of the BD chain (e.g., 0x50).
When I start the DMA now, I can read the status and control registers cyclically. Everything seems to be working as expected here. Even when I look at the current descriptor register, my buffer is always being written to cyclically, so everything is as expected. However, when I stop the DMA and look at the contents of the buffer, I get some unexpected data:
I use a generator to create a sine wave, which is also displayed correctly in the rear part of the buffer. However, the data in the front part is corrupted. Why is that? Has anyone gotten DMA to work in cyclic bd mode? I have found many incomplete forum posts on this topic. I also use buffer.invalidate() before reading the buffer for cache coherence.