Jump to content
  • 0

Questions about ZYNQ PS DMAC


Zlxt

Question


Hi everyone,I encountered difficulties when using ZYNQ PS DMAC, and hope someone can provide any solutions or ideas.
The problem is:
I wrote a QSPI module with AXI_LITE interface for my LCD screen,Then I want to use LVGL.
I allocated a 32-bit address for the tx register of the QSPI module, but actually only the lower 8 bits are used, and 8 bits are sent at a time. LVGL uses a 16-bit array to store RGB data.

Therefore, it is necessary to split the 16-bit data into two 8-bit data and send them to the tx register of QSPI.
I wanted to use ZYNQ's PS DMAC to do this for speed and lower CPU usage.

To simplify the problem, I think, is to a 16-bit array, let DMAC take 8 bits each time, and transfer to a 32 bit array.
So I  configured DMAC DmaCmd as:
XDmaPs_Cmd DmaCmd = {
    .ChanCtrl = {
        .SrcBurstSize = 1,
        .SrcBurstLen = 1,
        .SrcInc = 1,        // increment source address
        .DstBurstSize = 4,
        .DstBurstLen = 1,
        .DstInc = 1,        // Ignoring the configuration here, I want to be able to see how the data is mapped in memory after the transfer, so I didn't set it to 0.
    },
};
In this configuration, the expectation is that the DMAC will take 8 bits each time from the source address, expand to 32 bits, and write to the destination address (set zeros in the high bits).

But in fact, this configuration doesn't seem to let DMAC work. DMAC seems to work only if the source and destination address configurations are the same(BurstSize and BurstLen).

I don't want to write another C function to convert the LVGL color array to an 32-bit array,it would take a lot of CPU time to move the data around.

My board is Zynq-7020. I'm not particularly good at writing C programs.

Can anyone provide a better solution? Thanks.

Link to comment
Share on other sites

1 answer to this question

Recommended Posts

  • 0

Hi @Zlxt

Xilinx/AMD support may be able to provide more info about the DMAC than Digilent can.

If I understand correctly, you want to repeatedly write to the same 8-bit register in a PL peripheral, using DMAC to copy data from an array in DDR. From what I can tell, this ought to be possible with DMAC. The actual typing of the array doesn't matter so much, since it's still fundamentally bytes in memory. As long as they are aligned and consecutive, there's no issue with casting a u8 array to a u16 pointer or a u16 array to a u8 pointer.

So, the following should transfer a DMA_LENGTH length array located at Src to a single address. In this case, I tested it by DMAing to an AXI GPIO peripheral, gpio.BaseAddress is the data register for channel 1. A screenshot of a logic analyzer capture is attached.

Quote

dma_cmd.ChanCtrl.SrcBurstSize = 1;
dma_cmd.ChanCtrl.SrcBurstLen = 1;
dma_cmd.ChanCtrl.SrcInc = 1;
dma_cmd.ChanCtrl.DstBurstSize = 1;
dma_cmd.ChanCtrl.DstBurstLen = 1;
dma_cmd.ChanCtrl.DstInc = 0;
dma_cmd.BD.SrcAddr = (u32) Src;
dma_cmd.BD.DstAddr = gpio.BaseAddress;
dma_cmd.BD.Length = DMA_LENGTH;

However, if there are gaps between the bytes you want to copy from the source array, XDmaPs_Cmd doesn't have a way of describing a way of describing an address increment other than the burst size. Either source data needs to be consecutive in memory, or you need to write your own version of XDmaPs_BuildDmaProg, effectively hand-coding your own DMA microprogram. AXI DMA should have some mechanisms to support this, but the drivers are structured very differently.

Couple extra notes:

You can also see in XDmaPs_GenDmaProg that the product of burst size and burst length for source and destination must match:

Quote

    if (ChanCtrl->SrcBurstSize * ChanCtrl->SrcBurstLen
        != ChanCtrl->DstBurstSize * ChanCtrl->DstBurstLen) {
        return XST_FAILURE;
    }

Also, you might need to make sure that your AXI peripheral has a FIFO to buffer the data you're DMAing into it. The Zynq TRM has a couple of sections on how to approach this. See 9.4.3: https://docs.xilinx.com/r/en-US/ug585-zynq-7000-SoC-TRM

Thanks,

Arthur

image.png

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...