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
Visitor fnc
Visitor
230 Views
Registered: ‎07-22-2019

DMA decode error

Hi,

I'm having issues with the CDMA IP when trying to send data to a custom AXI Full Interface. The CDMA fails with an error status of 0x40 which means it has a decode error in the address.

I have a custom IP, named GP_Filter_Accelerator, with an AXI Full interface on port S01 and a Zynq PS which are connected in a block diagram. I have followed the SimplePoll Example from Xilinx documentation, so everything should work, but it doesn't.

I'm really lost and I need to proceed with the design, so any help will be really apreciated.

Thanks in advance.

xilinx-forum.pngBlock diagram

 

 

 

 

 

 

 

 

 

 

 

xilinx-forum-2.pngAddress map

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

xilinx-forum-3.pngError

 

 

 

 

 

 

 

 

 

 

 

 

 

The code I've used for the Zynq PS is the one shown below:

#include "platform.h"
#include "xparameters.h"
#include "xaxicdma.h"


#define DMA_CTRL_DEVICE_ID	XPAR_AXI_CDMA_0_DEVICE_ID
#define AXI_S01_BUFFER 		XPAR_GP_FILTER_ACCELERATOR_0_S01_AXI_BASEADDR

#define BUFFER_SIZE			64	// Length of the buffers for DMA transfer
#define RESET_LOOP_COUNT	10	// Number of times to check reset is done

/************************** Function Prototypes ******************************/
int init_cdma_ctrl();
static int doTransfer(XAxiCdma *instancePtr, int length, int retries);
int xAxiCdma_Poll(u16 deviceId, int numberOfTransfers, int numberOfTries);
static int checkData(u32 *srcPtr, u32 *dstPtr, int length);

/************************** Variable Definitions *****************************/
// Instance of the XAxiCdma
static XAxiCdma axiCdmaInstance;

// Source and Destination buffer for DMA transfer
volatile static u32 srcBuffer[BUFFER_SIZE] __attribute__ ((aligned (32)));
volatile static u32 *dstBuffer __attribute__ ((aligned (32)));

// Shared variables used to test the callback
volatile static int done = 0;	// DMA transfer is done
volatile static int error = 0;	// DMA Error occurs

int main() {

    xil_printf("\r\r\n*** START ***\r\r\n");
    init_platform();

	int result = init_cdma_ctrl();

    cleanup_platform();
    xil_printf("\r\n***  END  ***\r\r\n");
	return result;
}

int init_cdma_ctrl() {

	int status;
	const int numOfTries = 10;

	int deviceID = DMA_CTRL_DEVICE_ID;
	int numOfTransfer = 1;
	dstBuffer = (u32 *) AXI_S01_BUFFER;


	xil_printf("\r\n[I] init_cdma_ctrl: starting transfer routines... \r\n\r\n");

	// Run the polling transfer method
	status = xAxiCdma_Poll(deviceID, numOfTransfer, numOfTries);
	if (status != XST_SUCCESS) {
		xil_printf("[E] init_cdma_ctrl: xAxiCdma_Poll failed!\r\n");
		return XST_FAILURE;
	}

	xil_printf("\r\n[I] init_cdma_ctrl: transfer successful! \r\n");
	return XST_SUCCESS;

}

int xAxiCdma_Poll(u16 deviceId, int numberOfTransfers, int numberOfTries) {

	XAxiCdma_Config *cfgPtr;
	int status;

	// Initialize the XAxiCdma device
	cfgPtr = XAxiCdma_LookupConfig(deviceId);
	if (!cfgPtr) {
		xil_printf("[E] LookupConfig failed!\r\n");
		return XST_FAILURE;
	}

	status = XAxiCdma_CfgInitialize(&axiCdmaInstance, cfgPtr, cfgPtr->BaseAddress);
	if (status != XST_SUCCESS) {
		xil_printf("[E] CfgInitialize failed!\r\n");
		return XST_FAILURE;
	}

	// Disable interrupts, we use polling mode
	XAxiCdma_IntrDisable(&axiCdmaInstance, XAXICDMA_XR_IRQ_ALL_MASK);
    Xil_DCacheDisable();

	for (int i = 0; i < numberOfTransfers; ++i) {
		xil_printf("[I] ====== Transfer #%d ======\r\n", i);
		status = doTransfer(&axiCdmaInstance, BUFFER_SIZE, numberOfTries);
		if (status != XST_SUCCESS) {
			xil_printf("[E] Transfer failed!\r\n");
			return XST_FAILURE;
		}
	}

	return XST_SUCCESS;
}



static int doTransfer(XAxiCdma *instancePtr, int length, int retries) {

	int status;
	u32  *srcPtr;
	u32  *dstPtr;

	// Initialize the source buffer bytes with a pattern and the
	// the destination buffer bytes to zero
	srcPtr = (u32 *) srcBuffer;
	dstPtr = (u32 *) dstBuffer;
	xil_printf("[I] SrcPtr = 0x%x :: DstPtr = 0x%x\r\n", srcPtr, dstPtr);

	for (int i = 0; i < BUFFER_SIZE; ++i) {
		srcPtr[i] = i & 0xFF;
	}

	// Flush the SrcBuffer before the DMA transfer, in case the Data Cache is enabled
	Xil_DCacheFlushRange((UINTPTR)&srcBuffer, length);
#ifdef __aarch64__
	Xil_DCacheFlushRange((UINTPTR)&dstBuffer, length);
#endif

	// Try to start the DMA transfer
	while (retries) {
		--retries;
		status = XAxiCdma_SimpleTransfer(instancePtr, (UINTPTR)srcBuffer,
			(UINTPTR)dstBuffer, length, NULL, NULL);
		if (status == XST_SUCCESS) {
			break;
		}
	}

	// Return failure if failed to submit the transfer
	if (!retries) {
		xil_printf("[E] XAxiCdma_SimpleTransfer failed!\r\n");
		return XST_FAILURE;
	}

	// Wait until the DMA transfer is done
	while (XAxiCdma_IsBusy(instancePtr)) {
		/**Wait**/
	}

	//This is a poll method and error conditions not cleared by the driver.
	error = XAxiCdma_GetError(instancePtr);
	xil_printf("[I] GetError from XAxiCdma 0x%x\r\n", error);
	if (error != 0x0) {
		int timeOut = RESET_LOOP_COUNT;

		// Need to reset the hardware to restore to the correct state
		XAxiCdma_Reset(instancePtr);
		while (timeOut) {
			if (XAxiCdma_ResetIsDone(instancePtr)) {
				break;
			}
			--timeOut;
		}

		return XST_FAILURE;
	}

	// Transfer has been completed successfully, check data
	status = checkData(srcPtr, dstPtr, length);
	if (status != XST_SUCCESS) {
		xil_printf("[E] Check data failed!\r\n");
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}

static int checkData(u32 *srcPtr, u32 *dstPtr, int length) {

	// Invalidate the DestBuffer before receiving the data, in case the
	// Data Cache is enabled
#ifndef __aarch64__
	Xil_DCacheInvalidateRange((UINTPTR)dstPtr, length);
#endif

	for (int i = 0; i < length; ++i) {
		xil_printf("[I] checkData %d: 0x%x\t%d\r\n", i, dstPtr+i, dstPtr[i]);
		if ( dstPtr[i] != srcPtr[i]) {
			return XST_FAILURE;
		}
	}

	return XST_SUCCESS;
}
0 Kudos