UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Newbie bpm55
Newbie
3,200 Views
Registered: ‎07-29-2013

PL330 DMA Memory to Memory Transfer

The following code is an attempt on a Zedboard to do a memory to memory DMA transfer. I am not able to successfully complete a transfer and read the data in the destination memory location. Please let me know if there are functions in xdmaps.h or xdmaps.c included in this post that need to be called to make it function correctly. This is a baremetal application. 

 

/*
* main.c * Copy using DMA from memory to memory */ #include <stdio.h> #include "platform.h" /***************************** Include Files ********************************/ #include <string.h> #include "xstatus.h" #include "xdmaps.h" #include "xil_io.h" #include "xil_cache.h" #include "xil_printf.h" /************************** Constant Definitions ****************************/ /**************************** Type Definitions ******************************/ #define DST_ADDR 0x00100000+(1920*1080*4) #define SRC_ADDR DST_ADDR + 0x1000 #define CHANNEL 0 //void print(char *str); void dma_done(unsigned int channel, XDmaPs_Cmd *DmaCmd, void *CallbackRef) { int i, time; //gettimeofday(&t2,0); // time = t2.tv_sec*1000000 + t2.tv_usec - t1.tv_sec*1000000 - t1.tv_usec; // printf ("DMA success, time = %d us, b/w = %f MB/s!\n",time,(double)0.00390625/((double)time/(double)1000000)); printf("DMA Callback!\n"); for (i = 0; i < 1024; i++) if (*((int *) DST_ADDR + i) != i * 2) fprintf(stderr, "error: dst array doesn't match source, index=%d\n", i); //return 0; } void dma_fault(unsigned int channel, XDmaPs_Cmd *DmaCmd, void *CallbackRef) { fprintf(stderr, "DMA failure, fault type = %u!\n", (unsigned int) DmaCmd->ChanFaultType); } int main() { XDmaPs InstPtr; XDmaPs_Config *Config; XDmaPs_Cmd myCommand; int ret,i; int callback_ref; init_platform(); printf("Hello World\n\r"); printf("Program start!\n\r"); Config = XDmaPs_LookupConfig(XPAR_PS7_DMA_S_DEVICE_ID); ret = XDmaPs_CfgInitialize(&InstPtr, Config, XPAR_XDMAPS_1_BASEADDR); if (ret != XST_SUCCESS) { printf("Error with Config!\n\r"); return -1; } else { printf("Config Success! BaseAddress:0x%08X \n\r", InstPtr.Config.BaseAddress); printf("Config Success! Device ID:0x%08X \n\r", InstPtr.Config.DeviceId); } printf("Reset start!\n"); ret = XDmaPs_ResetChannel(&InstPtr, CHANNEL); if (ret < 0) { printf("Error SetDoneHandler\n"); return -1; } printf("Done handle start!\n"); ret = XDmaPs_SetDoneHandler(&InstPtr, CHANNEL, dma_done, (void *) &callback_ref); if (ret == XST_FAILURE) { printf("Error SetDoneHandler\n"); return -1; } printf("Fault handle start!\n"); ret = XDmaPs_SetFaultHandler(&InstPtr, dma_fault, (void *) &callback_ref); if (ret == XST_FAILURE) { printf("Error SetFaultHandler\n"); return -1; } XDmaPs_DoneISR_0(&InstPtr); for (i = 0; i < 1024; i++) *((int *) SRC_ADDR + i) = i * 2; //Setup the Channel Control Structure myCommand.ChanCtrl.EndianSwapSize = 8; myCommand.ChanCtrl.DstCacheCtrl = 0; myCommand.ChanCtrl.DstProtCtrl = 0; myCommand.ChanCtrl.DstBurstLen = 1; myCommand.ChanCtrl.DstBurstSize = 8; myCommand.ChanCtrl.DstInc = 1; myCommand.ChanCtrl.SrcCacheCtrl = 0; myCommand.ChanCtrl.SrcProtCtrl = 0; myCommand.ChanCtrl.SrcBurstLen = 1; myCommand.ChanCtrl.SrcBurstSize = 8; myCommand.ChanCtrl.SrcInc = 1; myCommand.GeneratedDmaProg = 0; myCommand.UserDmaProg = 0; //Setup the Block Descriptor Structure myCommand.BD.SrcAddr = SRC_ADDR; myCommand.BD.DstAddr = DST_ADDR; myCommand.BD.Length = 4096; printf("Status is: %X\n", *((int *) (XPAR_XDMAPS_1_BASEADDR + 0x100)) & 0xF); XDmaPs_Start(&InstPtr, CHANNEL, &myCommand, 0); if (ret != XST_SUCCESS) { printf("Error with Config!\n\r"); return 0; } else { printf("Gen Prog Success! BaseAddress:%d \n\r", myCommand.GeneratedDmaProgLength); printf("Block Desc Success! Device ID:%d \n\r", myCommand.BD.Length); } printf("Control Register is: %X\n", *((int *) (XPAR_XDMAPS_1_BASEADDR + 0x408))); for (i = 0; i < 1024; i++) if (*((int *) DST_ADDR + i) != i * 2) fprintf(stderr, "error: dst array doesn't match source, index=%d\n", i); //while (1) //; //printf("Address : 0x%08X",InstPtr.IsReady); //ret = XDmaPs_SelfTest(NULL); //printf("DMA Test Status: %d", ret); return 0; }

 

Thanks in advance for any and all help!!

0 Kudos
1 Reply
Newbie acespirit
Newbie
1,978 Views
Registered: ‎03-17-2015

Re: PL330 DMA Memory to Memory Transfer

you need to check your lscript.ld.

 

if memory region in "section to memory region mapping" is ps7_ddr_0_S_AXI_BASEADDR,

 

DDR(0x0010_0000 ~ 0x3fff_ffff) may be overwrited by your DMA code and by your standalone app.

 

so, it may be fixed if memory region in "section to memory region mapping" is changed to ps7_ram_0_S_AXI_BASEADDR.

 

this change is effect to

 

1. your DMA code is accessed to DDR(0x0010_0000 ~ 0x3fff_ffff)

 

2. your standalone app. is running in OCM memory(NOT DDR).

 

OR,  Src/Dst address in your DMA code need to be changed.

 

have a nice day.

 

0 Kudos