zedboard平台下DMA实现memory to memory传输

2019-07-13 09:24发布

/*
 * dma.c
 *
 *  Created on: 2014-12-16
 *      Author: zhoudengqing
 */




#include
#include "platform.h"
#include "xscugic.h"
#include "xdmaps.h"
#include "xil_exception.h"
#include "xil_types.h"
#include "xil_printf.h"




#define DMA_DEVICE_ID       XPAR_XDMAPS_1_DEVICE_ID //1
#define INTC_DEVICE_ID      XPAR_SCUGIC_SINGLE_DEVICE_ID  //0
#define DMA_FAULT_INTR      XPAR_XDMAPS_0_FAULT_INTR //45
#define DMA_DONE_INTR_0     XPAR_XDMAPS_0_DONE_INTR_0 //46
#define DMA_LENGTH          1024




void XDma_Config(u16 DeviceId);
void SetupInterrupt(XScuGic *GicPtr, XDmaPs *DmaPtr);
void DmaISR(unsigned int Channel, XDmaPs_Cmd *DmaCmd, void *CallbackRef);


static int Src[DMA_LENGTH];
static int Dst[DMA_LENGTH];


XDmaPs DmaInstance;
XScuGic GicInstance;


int main()
{
int Index;


init_platform();


printf(" zhou Edition zedboard Using Vivado&SDK ");


XDma_Config(DMA_DEVICE_ID);


for (Index = 0; Index < DMA_LENGTH; Index++)
{
printf("Dst[%d] = %d ", Index, Dst[Index]);
}


return 0;
}


void XDma_Config(u16 DeviceID)
{
int Index;
unsigned int Channel = 0;
volatile int Checked[XDMAPS_CHANNELS_PER_DEV];
XDmaPs_Config *DmaCfg;
XDmaPs *DmaInst = &DmaInstance;
XDmaPs_Cmd DmaCmd;


memset(&DmaCmd, 0, sizeof(XDmaPs_Cmd));


DmaCmd.ChanCtrl.SrcBurstSize = 4;
DmaCmd.ChanCtrl.SrcBurstLen = 4;
DmaCmd.ChanCtrl.SrcInc = 1;
DmaCmd.ChanCtrl.DstBurstSize = 4;
DmaCmd.ChanCtrl.DstBurstLen = 4;
DmaCmd.ChanCtrl.DstInc = 1;
DmaCmd.BD.SrcAddr = (u32)Src;
DmaCmd.BD.DstAddr = (u32)Dst;
DmaCmd.BD.Length = DMA_LENGTH * sizeof(int);


DmaCfg = XDmaPs_LookupConfig(DeviceID);
XDmaPs_CfgInitialize(DmaInst, DmaCfg, DmaCfg->BaseAddress);
SetupInterrupt(&GicInstance, DmaInst);


for (Index = 0; Index < DMA_LENGTH; Index++)
{
Src[Index] = DMA_LENGTH - Index;
}


for (Index = 0; Index < DMA_LENGTH; Index++)
{
Dst[Index] = 0;
}


Checked[Channel] = 0;


XDmaPs_SetDoneHandler(DmaInst, Channel, DmaISR, (void *)(Checked + Channel));
XDmaPs_Start(DmaInst, Channel, &DmaCmd, 0);
XDmaPs_Print_DmaProg(&DmaCmd);
}




void SetupInterrupt(XScuGic *GicPtr, XDmaPs *DmaPtr)
{
XScuGic_Config *GicConfig;




Xil_ExceptionInit();


GicConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);


XScuGic_CfgInitialize(GicPtr, GicConfig,GicConfig->CpuBaseAddress);


Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
    (Xil_ExceptionHandler)XScuGic_InterruptHandler,
    GicPtr);


XScuGic_Connect(GicPtr,DMA_FAULT_INTR,(Xil_InterruptHandler)XDmaPs_FaultISR,(void *)DmaPtr);




XScuGic_Connect(GicPtr,DMA_DONE_INTR_0,(Xil_InterruptHandler)XDmaPs_DoneISR_0,(void *)DmaPtr);


XScuGic_Enable(GicPtr, DMA_DONE_INTR_0);


Xil_ExceptionEnable();
}




void DmaISR(unsigned int Channel, XDmaPs_Cmd *DmaCmd, void *CallbackRef)
{


/* done handler */
volatile int *Checked = (volatile int *)CallbackRef;
int Index;
int Status = 1;
int *Src;
int *Dst;


Src = (int *)DmaCmd->BD.SrcAddr;
Dst = (int *)DmaCmd->BD.DstAddr;


/* DMA successful */
/* compare the src and dst buffer */
for (Index = 0; Index < DMA_LENGTH; Index++) {
if ((Src[Index] != Dst[Index]) ||
(Dst[Index] != DMA_LENGTH - Index)) {
Status = -XST_FAILURE;
}
}




*Checked = Status;
printf("DMA passed ");
}