/*
 * project_para.c
 *Bit defitiona of the Config registers
 *|-------------------------------------------------------------------------------------------------------------|
 *|Bit 12-11 | Bit 10 | Bit 9 |Bit 8 |Bit 7    |Bit 6 	 |Bit 5 	 |Bit 4  |Bit 3   |Bit 2     |Bit 1 |Bit 0  |
 *|-------------------------------------------------------------------------------------------------------------|
 *|Band width|settle  |sel4	  |sel3  |sel2/sync|sel1/step|sel0/resetn|test_en|conn_all|Start/Stop|mode	|Virtual|
 *|-------------------------------------------------------------------------------------------------------------|
 *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"
#include "DMA.h"
#include "xil_io.h"
#include "sleep.h"
//#include "FreeRTOS.h"
//#include "task.h" // for vTaskDelay


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

	/* 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
//	vTaskDelay(10);
	usleep(100);

	Xil_Out32(Resetn_Soft_reg_addr, 1);	// active low soft reset
//	vTaskDelay(10);
	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
//
////		vTaskDelay(10);
//		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
}

void HiCCE_DMA_Tranfer(unsigned int DMA_tmp_addr, unsigned int DMA_trans_size){
	int INTAN_ACK, SEL_INTAN, n = 0;
	unsigned int DMA_base = 0;

	do{
		INTAN_ACK = Xil_In32(Ack_intan_reg_addr);
#if DEBUG_HICCE == 1
		xil_printf("INTAN_ACK %d\r\n", INTAN_ACK);
#endif
		if(DMA_tmp_addr == INTAN_A_RX_BUF_BASE){
			n = 3;										// # bits for masking
			SEL_INTAN = 8;								// set mutiplex to INTAN A
			DMA_base = INTAN_A_RX_BUF_BASE;

		}else if(DMA_tmp_addr == INTAN_B_RX_BUF_BASE){
			n = 2;										// # bits for masking
			SEL_INTAN = 4;								// set mutiplex to INTAN B
			DMA_base = INTAN_B_RX_BUF_BASE;

		}else if(DMA_tmp_addr == INTAN_C_RX_BUF_BASE){
			n = 1;										// # bits for masking
			SEL_INTAN = 2;								// set mutiplex to INTAN D
			DMA_base = INTAN_C_RX_BUF_BASE;


		}else if(DMA_tmp_addr == INTAN_D_RX_BUF_BASE){
			n = 0;										// # bits for masking
			SEL_INTAN = 1;								// set mutiplex to INTAN D
			DMA_base = INTAN_D_RX_BUF_BASE;


		}else{
			n = 3;										// # bits for masking
			SEL_INTAN = 8;								// set mutiplex to INTAN A
			DMA_base = INTAN_A_RX_BUF_BASE;

		}
		INTAN_ACK = (INTAN_ACK>>n) & 1;				// masked the intan A

#if DEBUG_HICCE == 1
		xil_printf("INTAN_ACK shifted %d\r\n", INTAN_ACK);
#endif

	}while(INTAN_ACK != 1);

	Xil_Out32(read_intan_reg_addr, SEL_INTAN);
	usleep(100);
//	vTaskDelay(10);

#if DEBUG_HICCE == 1
	xil_printf("DMA_base = 0x%x\r\n", DMA_base);
	xil_printf("DMA_trans_size = %d\r\n", DMA_trans_size);
#endif

	// start dma transfer
	DMA_Transfer(DMA_base, DMA_trans_size);

#if DEBUG_HICCE == 1
	xil_printf("DMA transfer complete **** \r\n");
#endif

	// allow to fill again
	Xil_Out32(read_intan_reg_addr, 15);

}


/*
 * 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(unsigned int DMA_tmp_addr, unsigned int DMA_trans_size){
	DMA_Tranfer_sim(DMA_tmp_addr, DMA_trans_size);
}
