cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
sadhvisalaka
Contributor
Contributor
4,424 Views
Registered: ‎04-21-2017

AXI DMA TRANSFER

RECEIVING_SIDE(S2MM)

int main()
{

	


	 xil_printf ("initializing axi dma ...\n\r");
	 	InitializeAXIDMA ();

	 	//StartDMATransfer ( 0xa000000, 256 );

   		while (1) {}


    return 0;
}

int InitializeAXIDMA ( void ) {
	unsigned int tmpVal;

	tmpVal=Xil_In32 ( XPAR_AXI_DMA_0_BASEADDR + 0x30 );
	tmpVal=tmpVal | 0x1001;
	Xil_Out32 ( XPAR_AXI_DMA_0_BASEADDR + 0x30, tmpVal );
	tmpVal=Xil_In32 ( XPAR_AXI_DMA_0_BASEADDR + 0x30 );
	xil_printf ( "value for DMA control register : %x\n\r", tmpVal );

	return 0;
}

//Start DMA Transfer
void StartDMATransfer ( unsigned int dstAddress, unsigned int len ) {

	Xil_DCacheFlushRange((UINTPTR)dstAddress, len);
	//write destination address to S2MM_DA register.
	Xil_Out32 ( XPAR_AXI_DMA_0_BASEADDR + 0x48 , dstAddress );
	//write length to S2MM_LENGTH register.
	Xil_Out32 ( XPAR_AXI_DMA_0_BASEADDR + 0x58 , len );
}


sending_side(MM2S)

int main()
{

	xil_printf ("initializing axi dma ...\n\r");
	InitializeAXIDMA ();

	 	//Start the first DMA Transfer
   xil_printf ( "performing the first dma transfer.... press a key to begin....\n\r" );
   //getchar();
    	StartDMATransfer ( 0xb000000, 256 );

    		while (1) {}

    return 0;
}


int InitializeAXIDMA ( void ) {
	unsigned int tmpVal;

	tmpVal=Xil_In32 ( XPAR_AXI_DMA_0_BASEADDR + 0x00 );
	tmpVal=tmpVal | 0x1001;
	Xil_Out32 ( XPAR_AXI_DMA_0_BASEADDR + 0x00, tmpVal );
	tmpVal=Xil_In32 ( XPAR_AXI_DMA_0_BASEADDR + 0x00 );
	xil_printf ( "value for DMA control register : %x\n\r", tmpVal );

	return 0;
}

//Start DMA Transfer
void StartDMATransfer ( unsigned int dstAddress, unsigned int len )
{

	Xil_DCacheFlushRange((UINTPTR)dstAddress, len);
	//write destination address to S2MM_DA register.
	Xil_Out32 ( XPAR_AXI_DMA_0_BASEADDR + 0x18 , dstAddress );
	//write length to S2MM_LENGTH register.
	Xil_Out32 ( XPAR_AXI_DMA_0_BASEADDR + 0x28 , len );
}

I want to write 256 BYTES in DDR using AXI DMA. For DMA, .For every one micro second, i get 256 BYTES  in 256 clock cycles(Tp = 50 ns). I want to store those words in DDR.
Is it possible?
And If we write some data in ddr, when wiil TREADY of DMA be high in no of clock cycles (clock period is 20 MHz)?

 

AND I AM ABLE TO WRITE  first 256 bytes of data into the DDR , but after that I am not able to initiate the second  DMA transfer

can u please tell me what changes should I have to do in my design and in my ps code

 

pls find the attached BD and .c file

 

 

with regards

sadhvi

recieving_side.jpg
sending.jpg
0 Kudos
Reply
6 Replies
hbucher
Scholar
Scholar
4,416 Views
Registered: ‎03-22-2016

@sadhvisalaka 

If you used the standard API it would be much easier to help. 

Any of those hardcoded constants might be wrong

vitorian.com --- We do this for fun. Always give kudos. Accept as solution if your question was answered.
I will not answer to personal messages - use the forums instead.
0 Kudos
Reply
sadhvisalaka
Contributor
Contributor
4,357 Views
Registered: ‎04-21-2017

hi, thanks for the reply @hbucher

/******************************************************************************
*
* Copyright (C) 2010 - 2016 Xilinx, Inc.  All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
 *
 * @file xaxidma_example_simple_poll.c
 *
 * This file demonstrates how to use the xaxidma driver on the Xilinx AXI
 * DMA core (AXIDMA) to transfer packets in polling mode when the AXI DMA core
 * is configured in simple mode.
 *
 * This code assumes a loopback hardware widget is connected to the AXI DMA
 * core for data packet loopback.
 *
 * To see the debug print, you need a Uart16550 or uartlite in your system,
 * and please set "-DDEBUG" in your compiler options. You need to rebuild your
 * software executable.
 *
 * Make sure that MEMORY_BASE is defined properly as per the HW system. The
 * h/w system built in Area mode has a maximum DDR memory limit of 64MB. In
 * throughput mode, it is 512MB.  These limits are need to ensured for
 * proper operation of this code.
 *
 *
 * <pre>
 * MODIFICATION HISTORY:
 *
 * Ver   Who  Date     Changes
 * ----- ---- -------- -------------------------------------------------------
 * 4.00a rkv  02/22/11 New example created for simple DMA, this example is for
 *       	       simple DMA
 * 5.00a srt  03/06/12 Added Flushing and Invalidation of Caches to fix CRs
 *		       648103, 648701.
 *		       Added V7 DDR Base Address to fix CR 649405.
 * 6.00a srt  03/27/12 Changed API calls to support MCDMA driver.
 * 7.00a srt  06/18/12 API calls are reverted back for backward compatibility.
 * 7.01a srt  11/02/12 Buffer sizes (Tx and Rx) are modified to meet maximum
 *		       DDR memory limit of the h/w system built with Area mode
 * 7.02a srt  03/01/13 Updated DDR base address for IPI designs (CR 703656).
 * 9.1   adk  01/07/16 Updated DDR base address for Ultrascale (CR 799532) and
 *		       removed the defines for S6/V6.
 *
 * </pre>
 *
 * ***************************************************************************

 */
/***************************** Include Files *********************************/
#include "xaxidma.h"
#include "xparameters.h"
#include "xdebug.h"

#if defined(XPAR_UARTNS550_0_BASEADDR)
#include "xuartns550_l.h"       /* to use uartns550 */
#endif

/******************** Constant Definitions **********************************/

/*
 * Device hardware build related constants.
 */

#define DMA_DEV_ID		XPAR_AXIDMA_0_DEVICE_ID

#ifdef XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#define DDR_BASE_ADDR		XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#elif XPAR_MIG7SERIES_0_BASEADDR
#define DDR_BASE_ADDR	XPAR_MIG7SERIES_0_BASEADDR
#elif XPAR_MIG_0_BASEADDR
#define DDR_BASE_ADDR	XPAR_MIG_0_BASEADDR
#elif XPAR_PSU_DDR_0_S_AXI_BASEADDR
#define DDR_BASE_ADDR	XPAR_PSU_DDR_0_S_AXI_BASEADDR
#endif

#ifndef DDR_BASE_ADDR
#warning CHECK FOR THE VALID DDR ADDRESS IN XPARAMETERS.H, \
		 DEFAULT SET TO 0x01000000
#define MEM_BASE_ADDR		0x01000000
#else
#define MEM_BASE_ADDR		(DDR_BASE_ADDR + 0x1000000)
#endif

#define TX_BUFFER_BASE		(MEM_BASE_ADDR + 0x00100000)
#define RX_BUFFER_BASE		(MEM_BASE_ADDR + 0x00300000)
#define RX_BUFFER_HIGH		(MEM_BASE_ADDR + 0x004FFFFF)

#define MAX_PKT_LEN		0x20

#define TEST_START_VALUE	0xC

#define NUMBER_OF_TRANSFERS	10

/**************************** Type Definitions *******************************/


/***************** Macros (Inline Functions) Definitions *********************/


/************************** Function Prototypes ******************************/

#if (!defined(DEBUG))
extern void xil_printf(const char *format, ...);
#endif

int XAxiDma_SimplePollExample(u16 DeviceId);
static int CheckData(void);

/************************** Variable Definitions *****************************/
/*
 * Device instance definitions
 */
XAxiDma AxiDma;


/*****************************************************************************/
/*
* The entry point for this example. It invokes the example function,
* and reports the execution status.
*
* @param	None.
*
* @return
*		- XST_SUCCESS if example finishes successfully
*		- XST_FAILURE if example fails.
*
* @note		None.
*
******************************************************************************/
int main()
{
	int Status;

	xil_printf("\r\n--- Entering main() --- \r\n");

	/* Run the poll example for simple transfer */
	Status = XAxiDma_SimplePollExample(DMA_DEV_ID);

	if (Status != XST_SUCCESS) {

		xil_printf("XAxiDma_SimplePollExample: Failed\r\n");
		return XST_FAILURE;
	}

	xil_printf("XAxiDma_SimplePollExample: Passed\r\n");

	xil_printf("--- Exiting main() --- \r\n");

	return XST_SUCCESS;

}

#if defined(XPAR_UARTNS550_0_BASEADDR)
/*****************************************************************************/
/*
*
* Uart16550 setup routine, need to set baudrate to 9600, and data bits to 8
*
* @param	None.
*
* @return	None
*
* @note		None.
*
******************************************************************************/
static void Uart550_Setup(void)
{

	/* Set the baudrate to be predictable
	 */
	XUartNs550_SetBaud(XPAR_UARTNS550_0_BASEADDR,
			XPAR_XUARTNS550_CLOCK_HZ, 9600);

	XUartNs550_SetLineControlReg(XPAR_UARTNS550_0_BASEADDR,
			XUN_LCR_8_DATA_BITS);

}
#endif

/*****************************************************************************/
/**
* The example to do the simple transfer through polling. The constant
* NUMBER_OF_TRANSFERS defines how many times a simple transfer is repeated.
*
* @param	DeviceId is the Device Id of the XAxiDma instance
*
* @return
*		- XST_SUCCESS if example finishes successfully
*		- XST_FAILURE if error occurs
*
* @note		None
*
*
******************************************************************************/
int XAxiDma_SimplePollExample(u16 DeviceId)
{
	XAxiDma_Config *CfgPtr;
	int Status;
	int Tries = NUMBER_OF_TRANSFERS;
	int Index;
	u8 *TxBufferPtr;
	u8 *RxBufferPtr;
	u8 Value;

	TxBufferPtr = (u8 *)TX_BUFFER_BASE ;
	RxBufferPtr = (u8 *)RX_BUFFER_BASE;

	/* Initialize the XAxiDma device.
	 */
	CfgPtr = XAxiDma_LookupConfig(DeviceId);
	if (!CfgPtr) {
		xil_printf("No config found for %d\r\n", DeviceId);
		return XST_FAILURE;
	}

	Status = XAxiDma_CfgInitialize(&AxiDma, CfgPtr);
	if (Status != XST_SUCCESS) {
		xil_printf("Initialization failed %d\r\n", Status);
		return XST_FAILURE;
	}

	if(XAxiDma_HasSg(&AxiDma)){
		xil_printf("Device configured as SG mode \r\n");
		return XST_FAILURE;
	}

	/* Disable interrupts, we use polling mode
	 */
	XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
						XAXIDMA_DEVICE_TO_DMA);
	XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
						XAXIDMA_DMA_TO_DEVICE);

	Value = TEST_START_VALUE;

	for(Index = 0; Index < MAX_PKT_LEN; Index ++) {
			TxBufferPtr[Index] = Value;

			Value = (Value + 1) & 0xFF;
	}
	/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
	 * is enabled
	 */
	Xil_DCacheFlushRange((UINTPTR)TxBufferPtr, MAX_PKT_LEN);
#ifdef __aarch64__
	Xil_DCacheFlushRange((UINTPTR)RxBufferPtr, MAX_PKT_LEN);
#endif

	for(Index = 0; Index < Tries; Index ++) {


		Status = XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR) RxBufferPtr,
					MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);

		if (Status != XST_SUCCESS) {
			return XST_FAILURE;
		}

		Status = XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR) TxBufferPtr,
					MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);

		if (Status != XST_SUCCESS) {
			return XST_FAILURE;
		}

		while ((XAxiDma_Busy(&AxiDma,XAXIDMA_DEVICE_TO_DMA)) ||
			(XAxiDma_Busy(&AxiDma,XAXIDMA_DMA_TO_DEVICE))) {
				/* Wait */
		}

		Status = CheckData();
		if (Status != XST_SUCCESS) {
			return XST_FAILURE;
		}

	}

	/* Test finishes successfully
	 */
	return XST_SUCCESS;
}



/*****************************************************************************/
/*
*
* This function checks data buffer after the DMA transfer is finished.
*
* @param	None
*
* @return
*		- XST_SUCCESS if validation is successful.
*		- XST_FAILURE otherwise.
*
* @note		None.
*
******************************************************************************/
static int CheckData(void)
{
	u8 *RxPacket;
	int Index = 0;
	u8 Value;

	RxPacket = (u8 *) RX_BUFFER_BASE;
	Value = TEST_START_VALUE;

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

	for(Index = 0; Index < MAX_PKT_LEN; Index++) {
		if (RxPacket[Index] != Value) {
			xil_printf("Data error %d: %x/%x\r\n",
			Index, (unsigned int)RxPacket[Index],
				(unsigned int)Value);

			return XST_FAILURE;
		}
		Value = (Value + 1) & 0xFF;
	}

	return XST_SUCCESS;
}

,

 


actually I have tried the Xilinx standard API also for the simple DMA TRANSACTION. With that also I am facing the same problem. pls find the attached API  AND LET ME KNOW WHAT CHANGES I SHOULD DO.

WITH REGARDS
 SADHVI

0 Kudos
Reply
hbucher
Scholar
Scholar
4,351 Views
Registered: ‎03-22-2016

@sadhvisalaka

One thing I noticed is that your stream interfaces are disconnected. This way you wont transmit anything.

The example you put forward should go out the AXI DMA, through M_AXIS_MM2S then into FIFO then back to AXI DMA through S_AXIS_S2MM

 

vitorian.com --- We do this for fun. Always give kudos. Accept as solution if your question was answered.
I will not answer to personal messages - use the forums instead.
0 Kudos
Reply
sadhvisalaka
Contributor
Contributor
4,301 Views
Registered: ‎04-21-2017

@hbucher..hi

actually in my project I am transmitting 256 bytes of data from one board to another zynq board through DMA, FOR THIS PURPOSE I HAVE TAKEN OUT DMA DATA SIGNAL ALONG WITH  AXI CONTROL SIGNALS ALSO FROM ONE BOARD TO THE OTHER BOARD.

 I AM ABLE TO TRANSMIT THE 256 BYTE OF DATA FROM ONE BOARD TO OTHER BOARD FOR THE FIRST TIME . PROBLEM IS AFTER THAT DMA WILL STOP . BUT IN MY CASE I WANT TO TRANSMIT 256 BYTES OF DATA WHENEVER I CALL "DMA_TRANSFER " FUNCTION THIS IS NOT HAPPENING.

 

PLEASE HELP WITH THIS

 

WITH REGARDS

SADHVI

0 Kudos
Reply
hbucher
Scholar
Scholar
4,299 Views
Registered: ‎03-22-2016

@sadhvisalaka But in the code you presented you are initiating one send and one receive on the same processor.

The transmit will go through but the receive will be stuck waiting forever. 

Check out the while loop.

vitorian.com --- We do this for fun. Always give kudos. Accept as solution if your question was answered.
I will not answer to personal messages - use the forums instead.
0 Kudos
Reply
sadhvisalaka
Contributor
Contributor
4,274 Views
Registered: ‎04-21-2017

@hbucherhi

 

 

actually I wanted to design like that only. Receiving side it should wait in while loop then only it can able to receive the data from DMA.

 

WITH REGARDS

SADHVI

0 Kudos
Reply