/*
 * project_para.c
 *Bit defitiona of the Config registers
 *bit 12-11 : Band width selection bits
 *bit 10	: settle
 *bit 9-5	: sel0_reset, sel1_step, sel2_sync, sel3, sel4
 *bit 4		: test_en
 *bit 3		: conn_all
 *bit 2		: DAQ_Start
 *bit 1		: mode - (1-Sequential, 0- manual)
 *bit 0 	: Virtual mode
 *
 *
 *  Created on: Jul 15, 2018
 *      Author: Kasun
 */
#include "project_para.h"

//********* registers ***********//
#define reg_block_base_addr	XPAR_REG_BLOCK_0_S00_AXI_BASEADDR

#define config_intan_A_reg_addr	reg_block_base_addr+4*0
#define config_intan_B_reg_addr	reg_block_base_addr+4*1
#define config_intan_C_reg_addr reg_block_base_addr+4*2
#define config_intan_D_reg_addr reg_block_base_addr+4*3

#define read_intan_reg_addr		reg_block_base_addr+4*4

#define Resetn_Soft_reg_addr	reg_block_base_addr+4*5

#define Ack_intan_reg_addr		reg_block_base_addr+4*14		// input for uP

//*********** register values ************//


void init_HiCCE(void){
	/* intialize the DMA system*/
	DMA_init();

	/* Following 8 lines written for Auto sequential mode
		 * if you need manual mode comment these lines
		*/

	Xil_Out32(Resetn_Soft_reg_addr, 0);	// active low soft reset
	usleep(100);
	Xil_Out32(Resetn_Soft_reg_addr, 1);	// active low soft reset
	usleep(100);

		// reset the counters in intan chips
		Xil_Out32(config_intan_A_reg_addr, 6150);	// configure intan A
		Xil_Out32(config_intan_B_reg_addr, 6150);	// configure intan b
		Xil_Out32(config_intan_C_reg_addr, 6150);	// configure intan c
		Xil_Out32(config_intan_D_reg_addr, 6150);	// configure intan d

		// remove the reset
		Xil_Out32(config_intan_A_reg_addr, 6182);	// configure intan A 6246
		Xil_Out32(config_intan_B_reg_addr, 6182);	// configure intan b
		Xil_Out32(config_intan_C_reg_addr, 6182);	// configure intan c	6148
		Xil_Out32(config_intan_D_reg_addr, 6182);	// configure intan d


		/* Following 8 lines written for manual mode
		 * if you need Auto sequential mode uncomment these lines and comment above lines
		*/
//		/*
//		Xil_Out32(config_intan_A_reg_addr, 7172);	// fast settel for trancients
//		Xil_Out32(config_intan_B_reg_addr, 7172);	// fast settel for trancients
//		Xil_Out32(config_intan_C_reg_addr, 7172);	// fast settel for trancients
//		Xil_Out32(config_intan_D_reg_addr, 7172);	// fast settel for trancients
//
//		usleep(100);
//
//		Xil_Out32(config_intan_A_reg_addr, 6148);	// Normal oparation ch 0 - 6276
//		Xil_Out32(config_intan_B_reg_addr, 6180);	// Normal oparation ch 0
//		Xil_Out32(config_intan_C_reg_addr, 6148);	// Normal oparation ch 0
//		Xil_Out32(config_intan_D_reg_addr, 6148);	// Normal oparation ch 0
//		*/

		Xil_Out32(read_intan_reg_addr, 15);	// select the fifo (B - 4 C = 2)
}

void init_intan(void){
	if(strncmp(globalstr_intan, "INTAN_A",7)==0){
		Xil_Out32(read_intan_reg_addr, 8);
	}
	if(strncmp(globalstr_intan, "INTAN_B",7)==0){
		Xil_Out32(read_intan_reg_addr, 4);
	}
	if(strncmp(globalstr_intan, "INTAN_C",7)==0){
		Xil_Out32(read_intan_reg_addr, 2);
	}
	if(strncmp(globalstr_intan, "INTAN_D",7)==0){
		Xil_Out32(read_intan_reg_addr, 1);
	}
	if(strncmp(globalstr_intan, "ALL",3)==0){
		Xil_Out32(read_intan_reg_addr, 15);
	}
	else{

	}
}

void HiCCE_DMA_Tranfer(void){


	// start dma transfer
	if(strncmp(globalstr_intan, "INTAN_A",7)==0){
		// set mutiple to INTAN A
		if(((Xil_In32(Ack_intan_reg_addr))>>3) == 1){
			xil_printf("FIFO states %d \r\n",Xil_In32(Ack_intan_reg_addr)>>3);}
		DMA_Transfer(INTAN_A_RX_BUF_BASE);
		globalstr_intan = "INTAN_A";
		usleep(100);
	}
	else if(strncmp(globalstr_intan, "INTAN_B",7)==0){
		// set mutiple to INTAN B
		if(((Xil_In32(Ack_intan_reg_addr))>>2) == 1){
			xil_printf("FIFO states %d \r\n",Xil_In32(Ack_intan_reg_addr)>>2);
		}
		// start dma transfer
		DMA_Transfer(INTAN_B_RX_BUF_BASE);
		globalstr_intan = "INTAN_B";
		usleep(100);
	}
	else if(strncmp(globalstr_intan, "INTAN_C",7)==0){
	// set mutiple to INTAN C
		if(((Xil_In32(Ack_intan_reg_addr))>>1) == 1){
			xil_printf("FIFO states %d \r\n",Xil_In32(Ack_intan_reg_addr)>>1);
		}
		// start dma transfer
		XTime_GetTime(&tStart);
		DMA_Transfer(INTAN_C_RX_BUF_BASE);
		XTime_GetTime(&tEnd);
		globalstr_intan = "INTAN_C";
		usleep(100);
	////
	}
	else if(strncmp(globalstr_intan, "INTAN_D",7)==0){
	// set mutiple to INTAN D
		if((Xil_In32(Ack_intan_reg_addr)) == 1){
			xil_printf("FIFO states %d \r\n",Xil_In32(Ack_intan_reg_addr));
		}
		// start dma transfer
		DMA_Transfer(INTAN_D_RX_BUF_BASE);
		globalstr_intan = "INTAN_D";
		usleep(100);
	}
	else if(strncmp(globalstr_intan, "ALL",3)==0){
		Xil_Out32(read_intan_reg_addr, 8);
		if(((Xil_In32(Ack_intan_reg_addr))>>3) == 1);
		DMA_Transfer(INTAN_A_RX_BUF_BASE);
		usleep(10);

		Xil_Out32(read_intan_reg_addr, 4);
		if(((Xil_In32(Ack_intan_reg_addr))>>2) == 1);
		DMA_Transfer(INTAN_B_RX_BUF_BASE);
		usleep(10);

		Xil_Out32(read_intan_reg_addr, 2);
		if(((Xil_In32(Ack_intan_reg_addr))>>1) == 1);
		DMA_Transfer(INTAN_C_RX_BUF_BASE);
		usleep(10);

		Xil_Out32(read_intan_reg_addr, 1);
		if((Xil_In32(Ack_intan_reg_addr)) == 1);
		DMA_Transfer(INTAN_D_RX_BUF_BASE);
		usleep(10);

		globalstr_intan= "ALL";
	}






//	printf("Output took %llu clock cycles.\n", 2*(tEnd - tStart));
//	printf("Output took %.2f us.\n", 1.0 * (tEnd - tStart) / (COUNTS_PER_SECOND/1000000));
}

void data_gen_ramp(int datasize){
	int i;
	/* initialize data buffer being sent */
	for (i = 0; i < datasize; i++)
		send_buf[i] = (i % 10) + '0';
}

/*
 * 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 HiCCE_DMA_Tranfer_sim(void){
	int i;
	int x = 0;
	for(i = 0; i < data_size_words; i++){
		x = rand()%1000;
		Xil_Out32(DMA_RX_BASEADDR+4*i,i+x);
	}
	globalstr_intan = "INTAN_A";
	eTxCnt = 0;
//	xil_printf("Dma Transfer complete .. \n\r");
}
