本人在用Vivado CDMA IP核做数据传输实验过程中发现,SDK文件夹下的example cdma代码并没有将源区域的数据传输给目的区域,但是从返回给Status的值来看又是成功传输,不是很能理解。目前猜测或许是声明两块内存区域时,
volatile static u8 SrcBuffer[BUFFER_BYTESIZE] attribute ((aligned (64)));
volatile static u8 DestBuffer[BUFFER_BYTESIZE] attribute ((aligned (64)));
这两个声明语句造成的这个问题,有没有大神了解这方面的,烦请为我解答一二。
如下是SDK代码
#include "xaxicdma.h"
#include "xdebug.h"
#include "xil_exception.h"
#include "xil_cache.h"
#include "xparameters.h"
#include "xintc.h"
#define DMA_CTRL_DEVICE_ID XPAR_AXICDMA_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#define DMA_CTRL_IRPT_INTR XPAR_INTC_0_AXICDMA_0_VEC_ID
#define BUFFER_BYTESIZE 8 //Length of the buffers for DMA transfer
#define NUMBER_OF_TRANSFERS 1 //Number of simple transfers to do
static int DoSimpleTransfer(XAxiCdma *InstancePtr, int Length, int Retries);
static void Example_CallBack(void *CallBackRef, u32 IrqMask, int *IgnorePtr);
static int SetupIntrSystem(XIntc *IntcInstancePtr, XAxiCdma *InstancePtr,
u32 IntrId);
static void DisableIntrSystem(XIntc *IntcInstancePtr, u32 IntrId);
int XAxiCdma_SimpleIntrExample(XIntc *IntcInstancePtr, XAxiCdma *InstancePtr,
u16 DeviceId,u32 IntrId);
static XAxiCdma AxiCdmaInstance; //Instance of the XAxiCdma
static XIntc IntcController; //Instance of the Interrupt Controller
/* Source and Destination buffer for DMA transfer. */
volatile static u8 SrcBuffer[BUFFER_BYTESIZE] __attribute__ ((aligned (64)));
volatile static u8 DestBuffer[BUFFER_BYTESIZE] __attribute__ ((aligned (64)));
/* Shared variables used to test the callbacks.*/
volatile static int Done = 0; //Dma transfer is done
volatile static int Error = 0; // Dma Bus Error occurs
int main()
{
int Status;
xil_printf("\r\n--- Entering main() --- \r\n");
/* Run the interrupt example for simple transfer
*/
Status = XAxiCdma_SimpleIntrExample(&IntcController, &AxiCdmaInstance,
DMA_CTRL_DEVICE_ID,DMA_CTRL_IRPT_INTR);
if (Status != XST_SUCCESS) {
xil_printf("XAxiCdma_SimpleIntrExample: Failed\r\n");
return XST_FAILURE;
}
xil_printf("XAxiCdma_SimpleIntrExample: Passed\r\n");
xil_printf("--- Exiting main() --- \r\n");
return XST_SUCCESS;
}
int XAxiCdma_SimpleIntrExample(XIntc *IntcInstancePtr, XAxiCdma *InstancePtr,
u16 DeviceId,u32 IntrId)
{
XAxiCdma_Config *CfgPtr;
int Status;
int SubmitTries = 10; /* Retry to submit */
int Tries = NUMBER_OF_TRANSFERS;
int Index;
/* Initialize the XAxiCdma device.
*/
CfgPtr = XAxiCdma_LookupConfig(DeviceId);
if (!CfgPtr) {
return XST_FAILURE;
}
else
xil_printf("Config Success\n");
Status = XAxiCdma_CfgInitialize(InstancePtr, CfgPtr, CfgPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
else
xil_printf("Config Initialize Success\n");
/* Setup the interrupt system
*/
Status = SetupIntrSystem(IntcInstancePtr, InstancePtr, IntrId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
else
xil_printf("Setup IntrSystem Success\n");
/* Enable all (completion/error/delay) interrupts
*/
XAxiCdma_IntrEnable(InstancePtr, XAXICDMA_XR_IRQ_ALL_MASK);
for (Index = 0; Index < Tries; Index++) {
Status = DoSimpleTransfer(InstancePtr,
BUFFER_BYTESIZE, SubmitTries);
if(Status != XST_SUCCESS) {
DisableIntrSystem(IntcInstancePtr, IntrId);
return XST_FAILURE;
}
else
xil_printf("DoSimpleTransfer Success\n");
}
/* Test finishes successfully, clean up and return
*/
DisableIntrSystem(IntcInstancePtr, IntrId);
return XST_SUCCESS;
}
/* This function does one simple transfer
InstancePtr is a pointer to the XAxiCdma instance
Length is the transfer length
Retries is how many times to retry on submission
*/
static int DoSimpleTransfer(XAxiCdma *InstancePtr, int Length, int Retries)
{
u32 Index;
u8 *SrcPtr;
u8 *DestPtr;
int Status;
Done = 0;
Error = 0;
/* Initialize the source buffer bytes with a pattern and the
* the destination buffer bytes to zero
*/
SrcPtr = (u8 *)SrcBuffer;
DestPtr = (u8 *)DestBuffer;
for (Index = 0; Index < Length; Index++) {
SrcPtr[Index] = Index & 0xFF;
DestPtr[Index] = 0;
}
xil_printf("Source and Destination Buffer Initialization Success\n");
/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
* is enabled
*/
Xil_DCacheFlushRange((UINTPTR)&SrcBuffer, Length);
//#ifdef __aarch64__
Xil_DCacheFlushRange((UINTPTR)&DestBuffer, Length);
//#endif
xil_printf("Flush Source and Destination Success\n");
/* Try to start the DMA transfer
*/
while (Retries) {
Retries --;
Status = XAxiCdma_SimpleTransfer(InstancePtr, (u32)SrcBuffer,
(u32)DestBuffer, Length, Example_CallBack,
(void *)InstancePtr);
if (Status == XST_SUCCESS) {
xil_printf("CDMA Transfer Success\n");
break;
}
else
xil_printf("CDMA SimpleTransfer Fail\n");
}
/*if (Retries) {
xil_printf("1 Fail\n");
return XST_FAILURE;
}*/
/* Wait until the DMA transfer is done
*/
while (!Done && !Error) {
/* Wait */
}
if (Error) {
xil_printf("Error Occur\n");
return XST_FAILURE;
}
/* Invalidate the DestBuffer before receiving the data, in case the
* Data Cache is enabled
*/
//#ifndef __aarch64__
Xil_DCacheInvalidateRange((UINTPTR)&DestBuffer, Length);
//#endif
/* Transfer completes successfully, check data
*
* Compare the contents of destination buffer and source buffer
*/
for (Index = 0; Index < Length; Index++) {
if ( DestPtr[Index] != SrcPtr[Index]) {
xil_printf("Source and Destination not Match\n");
/*for(u32 i = 0;i < Length; i++)
{
xil_printf("\nsrc:%x,dest:%x\n",SrcPtr[i],DestPtr[i]);
}*/
//return XST_FAILURE;
}
else
xil_printf("Source and Destination Match\n");
}
return XST_SUCCESS;
}
static int SetupIntrSystem(XIntc *IntcInstancePtr, XAxiCdma *InstancePtr,
u32 IntrId)
{
int Status;
/*
* Initialize the interrupt controller driver
*/
Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Connect the driver interrupt handler
* It will call the example callback upon transfer completion
*/
Status = XIntc_Connect(IntcInstancePtr, IntrId,
(XInterruptHandler)XAxiCdma_IntrHandler,
(void *)InstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Start the interrupt controller such that interrupts are enabled for
* all devices that cause interrupts. Specify real mode so that the DMA
* engine can generate interrupts through the interrupt controller
*/
Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Enable the interrupt for the DMA engine
*/
XIntc_Enable(IntcInstancePtr, IntrId);
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XIntc_InterruptHandler,
(void *)IntcInstancePtr);
Xil_ExceptionEnable();
return XST_SUCCESS;
}
/*Callback function for the simple transfer. It is called by the driver's
interrupt handler.
CallBackRef is the reference pointer registered through
transfer submission. In this case, it is the pointer to the
driver instance
IrqMask is the interrupt mask the driver interrupt handler
passes to the callback function.
IgnorePtr is a pointer that is ignored by simple callback
function*/
static void Example_CallBack(void *CallBackRef, u32 IrqMask, int *IgnorePtr)
{
if (IrqMask & XAXICDMA_XR_IRQ_ERROR_MASK) {
Error = FALSE;
//Error = TRUE;
//xil_printf("Error 1\n");
}
if (IrqMask & XAXICDMA_XR_IRQ_IOC_MASK) {
Done = TRUE;
xil_printf("CDMA Transfer Done\n");
}
}
static void DisableIntrSystem(XIntc *IntcInstancePtr, u32 IntrId)
{
/* Disconnect the interrupt
*/
XIntc_Disconnect(IntcInstancePtr, IntrId);
}