/*
 * DMA.c
 *
 *  Created on: Feb 20, 2017
 *      Author: Kasun
 */
#include "DMA.h"

int DMA_init(unsigned int PKT_LEN_WORDS){
	Xil_Out32(PACKET_LENGTH_BASEADDR, PKT_LEN_WORDS);

	int Status;
	XAxiDma_Config *CfgPtr;

	u16 DeviceId = DMA_DEV_ID;

	/* 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);


	/* Test finishes successfully */
	return XST_SUCCESS;
}


int DMA_Transfer(unsigned int Intan_RX_BUF_BASE, unsigned int PKT_LEN_BYTES){
	int Status;
	u8 *RxBufferPtr;
	//RxBufferPtr = (u32 *)RX_BUFFER_BASE;
	RxBufferPtr = (u8 *)Intan_RX_BUF_BASE;
	//xil_printf("RxBufferPtr = 0x%x, %d\r\n", RxBufferPtr, XAxiDma_Busy(&AxiDma,XAXIDMA_DEVICE_TO_DMA));


	/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache is enabled */
	Xil_DCacheFlushRange((u32) RxBufferPtr, PKT_LEN_BYTES);

	Status = XAxiDma_SimpleTransfer(AxiDma,(u32) RxBufferPtr, PKT_LEN_BYTES, XAXIDMA_DEVICE_TO_DMA);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	while (XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA)) {
		/* Wait */
	}
//	xil_printf("DMA transfer completed \r\n");
	return XST_SUCCESS;
}


/******************************************************************************/
#ifdef CHECK_DATA
static int CheckData(void){
	u32 *RxPacket;
	int Index = 0;
	volatile u32 *Rx_k = *(volatile u32 (*)[MAX_PKT_LEN])(RX_BUFFER_BASE+4*MAX_PKT_LEN*n);


	RxPacket = (u32 *) RX_BUFFER_BASE;

	/* Invalidate the DestBuffer before receiving the data, in case the
	 * Data Cache is enabled
	 */
	Xil_DCacheInvalidateRange((u32)RxPacket, MAX_PKT_LEN);

	xil_printf("Data received: ");
	for(Index = 0; Index < 32; Index++) {
		xil_printf("0x%X ", (unsigned int)Rx_k[Index]);
	}
	xil_printf("\r\n");

	return XST_SUCCESS;
}
#endif

/*
 * following code snippet can be used for mimic the DMA transfer for Ethernet debugging
 * x is a random variable whose numbers are between 0 to 1000
 */
void DMA_Tranfer_sim(unsigned int DMA_addr, int DMA_size){
	int i;
	int x = 0;
	int dsize = DMA_size/4;

	for(i = 0; i < dsize; i++){
		x = rand()%1000;
		Xil_Out32(DMA_addr+4*i,i+x);
	}
}
