# DMA Cyclic Mode Operation - Unable to stream data

**URL:** <https://discuss.pynq.io/t/dma-cyclic-mode-operation-unable-to-stream-data/6591>\
**Category:** Support\
**Created:** [January 31, 2024, 11:06am UTC](https://discuss.pynq.io/t/dma-cyclic-mode-operation-unable-to-stream-data/6591 "2024-01-31T11:06:14Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![sramk](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/sramk/32/5200_2.png) [@sramk](https://discuss.pynq.io/u/sramk)\
**Post date:** [January 31, 2024, 11:06am UTC](https://discuss.pynq.io/t/dma-cyclic-mode-operation-unable-to-stream-data/6591/1 "2024-01-31T11:06:14Z")

</div>

Hello

I am working with ZCU111 board and quite new to PYNQ especially with DMA. I want to stream some large chunk of data from DDR to PL through MM2S port of DMA and want to play the data cyclically.

I am aware that Cyclic mode requires SG enabled and is not officially supported. So I will try to program the registers. So I made a design as below:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/9/9901bf70745abd3c2b4e59e530d733f8bb43e7d5.png)

The DMA settings are:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/7/7c9f5b9318a3d083c04fef3aed22d0a6dc9c3255.png)

The True Dual Port BRAM write and read widths are 32 and has depth of 2048.  
The Address mapping is as follows:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/7/7e545481d4598e95bb9f2db172cbce2e00efcb2b.png)

To test initially I generated two buffers as follows:

```auto
from pynq import MMIO
mmio_dma=MMIO(ol.ip_dict['axi_dma_0']['phys_addr'],ol.ip_dict['axi_dma_0']['addr_range'])
mmio_bram_ps=MMIO(0x00_A000_0000,8192)
mmio_bram_sg=MMIO(0x0000_0000_A000_0000,8192)

data_size = 100
input_buffer = allocate(shape=(data_size,), dtype=np.uint16)
input_buffer2 = allocate(shape=(data_size,), dtype=np.uint16)
for i in range(data_size):
    input_buffer[i]=i+0x0000
    input_buffer2[i]=0x00C8-i

```

I thought to use BRAM to hold descriptors. So I am programming the descriptors into BRAM as follows (as per instructions given in PG021 Table 2-25[AXI DMA LogiCore IP](https://docs.xilinx.com/viewer/book-attachment/ePquvyIHSl7mKfi0ecEn4Q/CPPzqKuxCU1Q4a3rXOA1jw))

```auto
mmio_bram_ps.write(0x00,mmio_bram_ps.base_addr+0x34)
mmio_bram_ps.write(0x04,0)
mmio_bram_ps.write(0x08,input_buffer.physical_address)
mmio_bram_ps.write(0x0C,0)
mmio_bram_ps.write(0x10,0)
mmio_bram_ps.write(0x14,0)
mmio_bram_ps.write(0x18,0x08000100)
mmio_bram_ps.write(0x1C,0)
mmio_bram_ps.write(0x20,0)
mmio_bram_ps.write(0x24,0)
mmio_bram_ps.write(0x28,0)
mmio_bram_ps.write(0x2C,0)
mmio_bram_ps.write(0x30,0)

mmio_bram_ps.write(0x34,mmio_bram_ps.base_addr)
mmio_bram_ps.write(0x38,0)
mmio_bram_ps.write(0x3C,input_buffer2.physical_address)
mmio_bram_ps.write(0x40,0)
mmio_bram_ps.write(0x44,0)
mmio_bram_ps.write(0x48,0)
mmio_bram_ps.write(0x4C,0x04000100)
mmio_bram_ps.write(0x50,0)
mmio_bram_ps.write(0x54,0)
mmio_bram_ps.write(0x58,0)
mmio_bram_ps.write(0x5C,0)
mmio_bram_ps.write(0x60,0)
mmio_bram_ps.write(0x64,0)

```

After this I am programming the current descriptor according to steps given in PG021 for SG mode and DMA Register Address Map ([https://docs.xilinx.com/r/en-US/pg021\_axi\_dma/AXI-DMA-Register-Address-Map](https://docs.xilinx.com/r/en-US/pg021_axi_dma/AXI-DMA-Register-Address-Map))

```auto
mmio_dma.write(0x08,mmio_bram_ps.base_addr)
mmio_dma.write(0x0C,0)
mmio_dma.write(0x00,0x00010013)

mmio_dma.write(0x10,mmio_bram_ps.base_addr+0x34)
#mmio_dma.write(0x10,0x50)
mmio_dma.write(0x14,0)

```

Even after programming this way following the procedure, I am getting at the output only the contents of first buffer. Second buffer contents are not being streamed.

 ![image](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/4/4349f1087e1ecf16f631556147330eea5bec113f.png)

Where am I making a mistake? Please help.

Thank You

---

<div class="post-metadata">

**Author:** ![joshgoldsmith](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/joshgoldsmith/32/5347_2.png) [@joshgoldsmith](https://discuss.pynq.io/u/joshgoldsmith)\
**Post date:** [January 31, 2024, 11:41am UTC](https://discuss.pynq.io/t/dma-cyclic-mode-operation-unable-to-stream-data/6591/2 "2024-01-31T11:41:34Z")

</div>

Hi sramk

If you are using PYNQ v3.0.1 then you should be able to use cyclic mode with the PYNQ DMA driver.

Although undocumented, you can have a look through [the code that implements it](https://github.com/Xilinx/PYNQ/blob/v3.0.1/pynq/lib/dma.py) (search for “cyclic”).

You can use it in much the same way as you would with other DMA transfers, but explicitly setting the `cyclic` parameter to `True` e.g. `dma.sendchannel.transfer(buffer, cyclic=True)`. It is set to `False` by default.

A few things to note about cyclic mode:

- It is only available on the `sendchannel`, _not_ the `recvchannel`
- The `wait()` function it not available.
- Use the `stop()` function to halt operation.

Hope this helps,

Josh

---

<div class="post-metadata">

**Author:** ![sramk](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/sramk/32/5200_2.png) [@sramk](https://discuss.pynq.io/u/sramk)\
**Post date:** [January 31, 2024, 11:56am UTC](https://discuss.pynq.io/t/dma-cyclic-mode-operation-unable-to-stream-data/6591/3 "2024-01-31T11:56:22Z")

</div>

Hi @joshgoldsmith

Thank you for the info. But I am using PYNQ 2.7. Can you help me resolve this issue?

---

<div class="post-metadata">

**Author:** ![joshgoldsmith](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/joshgoldsmith/32/5347_2.png) [@joshgoldsmith](https://discuss.pynq.io/u/joshgoldsmith)\
**Post date:** [January 31, 2024, 12:17pm UTC](https://discuss.pynq.io/t/dma-cyclic-mode-operation-unable-to-stream-data/6591/4 "2024-01-31T12:17:34Z")

</div>

It might be possible to swap out the v3.0.1 driver for the v2.7 one. I Haven’t tested this, so there might be some issues, but it’s worth trying at least.

Josh
