#ifdef BUP_DIAGS
#include <stdio.h>
#include "apposmacro.h"
#define UINT32 unsigned int

extern int printDiags;
extern int bup_bme;

//#define DEBUG_MSG

/*--------------------------------------------------------*/
void bup_InitSdramCO (int x16, int OpenPage)
{
	UINT32 CtrlData = ((OpenPage&0x1)<<11) | ((x16&0x1)<<8) | 0x7b;
//  printf ("\tprogramming EMI_CTRL to: 0x%x\n",CtrlData);
	testPIOWrite (bup_bme,0xe0038000,CtrlData);
	testPIOWrite (bup_bme,0xe0038020,0x00000004);
	testPIOWrite (bup_bme,0xe0038004,0x00000877);	  //for 140Mhz memclk 
	testPIOWrite (bup_bme,0xe003800c,0x00000000);
	testPIOWrite (bup_bme,0xe0038008,0x00000000);
	testPIOWrite (bup_bme,0xe0038008,0x00000000);
	testPIOWrite (bup_bme,0xe0038010,0x00000000);


}
void bup_InitSdramCPE ()
{
#ifdef CPE_40
	testPIOWrite (bup_bme,0xe0038000,0x7c);
	testPIOWrite (bup_bme,0xe0038004,0x00000134);
#elif CPE_30
	testPIOWrite (bup_bme,0xe0038000,0x37d);
	testPIOWrite (bup_bme,0xe0038004,0x00000500);
#endif
	testPIOWrite (bup_bme,0xe003800c,0x00000000);
	testPIOWrite (bup_bme,0xe0038008,0x00000000);
	testPIOWrite (bup_bme,0xe0038008,0x00000000);
	testPIOWrite (bup_bme,0xe0038010,0x00000000);
}

#ifdef CPE_40
void InitSdramCPE4Rand (int CtrlData, int ba)
{
  testPIOWrite (1,0xe0038000,CtrlData);
  testPIOWrite (1,0xe0038020,ba);
  testPIOWrite (1,0xe0038004,0x00000134);   //for 35 memclk 
  testPIOWrite (1,0xe003800c,0x00000000);
  testPIOWrite (1,0xe0038008,0x00000000);
  testPIOWrite (1,0xe0038008,0x00000000);
  testPIOWrite (1,0xe0038010,0x00000000);
}
#endif

//-----------------------------------------------------------
void bup_InitSdramCORand (int CtrlData, int ba)
{
	testPIOWrite (bup_bme,0xe0038000,CtrlData);
	testPIOWrite (bup_bme,0xe0038020,ba);
	testPIOWrite (bup_bme,0xe0038004,0x00000877);	  //for 140Mhz memclk 
	testPIOWrite (bup_bme,0xe003800c,0x00000000);
	testPIOWrite (bup_bme,0xe0038008,0x00000000);
	testPIOWrite (bup_bme,0xe0038008,0x00000000);
	testPIOWrite (bup_bme,0xe0038010,0x00000000);
}
/*--------------------------------------------------------*/
void bup_WriteSdramCO (int StartAddr, int NumBytes, UINT32 StartData)
{
	UINT32 SdramAddr;
	UINT32 data;
	int BaseAddr;
	int SdramMaxAddr;
	int i;

	data = StartData;
	SdramMaxAddr = StartAddr + NumBytes;
	for (i=StartAddr; i<SdramMaxAddr; i=i+4)
	{
		SdramAddr = i & 0xffffffff;
		tpw (bup_bme,SdramAddr,data);
#ifdef DEBUG_MSG
		printf ("\tSDRAM Address : 0x%x\t WriteData : 0x%x\n",SdramAddr, data);
#endif
		data++;
	}
}
/*--------------------------------------------------------*/
int bup_ReadSdramCO (int StartAddr, int NumBytes, UINT32 StartData)
{
	UINT32 SdramAddr;
	UINT32 data,ExpData;
	int BaseAddr;
	int SdramMaxAddr;
	int i;
	int flag = 0;

	data = 0xbad;
	ExpData = StartData;
	SdramMaxAddr = StartAddr + NumBytes;
	for (i=StartAddr; i<SdramMaxAddr; i=i+4)
	{
		SdramAddr = i & 0xffffffff;
		data = testPIORead1 (bup_bme,SdramAddr);
//printf("data = %x\n", data);
		if (NumBytes == 1)
		{
			data = data & 0xff000000;
			ExpData = ExpData & 0xff000000;
		}
		else if (NumBytes == 2)
		{
			data = data & 0xffff0000;
			ExpData = ExpData & 0xffff0000;
		}
		else if (NumBytes == 3)
		{
			data = data & 0xffffff00;
			ExpData = ExpData & 0xffffff00;
		}

		if (data != ExpData)
		{
			flag = 1;
#ifdef DEBUG_MSG
#else
			break;
#endif
		}
		ExpData++;
		NumBytes = NumBytes-4;
	}
#ifdef DEBUG_MSG
	if (!flag)
	{
		printf ("\tSDRAM Data read/compare OK .........\n");
	}
	else
	{
		printf ("\tSDRAM Data compare ERROR .........\n");
	}
#endif  
	return(flag);
}
//---------------------------------------------------------------
void bup_SdramBasic ()
{
	int testfail;

	bup_WriteSdramCO (0x40000000,1000,0x11223344);
	testfail = bup_ReadSdramCO (0x40000000,1000,0x11223344);
	printf ("\n");
	if (testfail)
	{
		printf ("*************************************************\n"); 
		printf ("\tSDRAM basic test FAILED\n");
		printf ("*************************************************\n");
	}
	else if (printDiags)
	{
		printf ("*************************************************\n");
		printf ("\tSDRAM basic test PASSED\n");
		printf ("*************************************************\n");
	}

}
/*--------------------------------------------------------*/
int bup_SdramDma (int NumBytes, UINT32 StartData, int msg, int whichDMA)
{
	int i = 0;
	UINT32 data1 = 0x0;
	UINT32 CcrReg;
	int fail = 0;


	whichDMA*=4;

	bup_WriteSdramCO (0x40000000, NumBytes, StartData);  /*write SDRAM 100 locations*/

	testPIOWrite (bup_bme,0xe0030040+whichDMA,0x80000000);  /*set software DMA request*/
	testPIOWrite (bup_bme,0xe0030080+whichDMA,0x40000000);  /*set source address*/
	testPIOWrite (bup_bme,0xe00300c0+whichDMA,0x40080000);  /*set dest address*/
	CcrReg = 0x00001011 | (NumBytes << 16);
	testPIOWrite (bup_bme,0xe0030000+whichDMA,CcrReg);  /*Load DMA ccr register to start DMA*/
	taskDelay(10);
	while (!(data1 & 0x100))  /*polling for DMA done bit*/
	{

		iposTaskDelay(10);
		data1 = testPIORead1 (bup_bme,0xe0030000+whichDMA);
		i++;
		if (i == 300)
		{
			i = 0;
			printf ("********* Time out in DMA done polling1 ********\n");
			break;
		}
	}

	fail = bup_ReadSdramCO (0x40080000,NumBytes,StartData);
	return fail;
}
/*--------------------------------------------------------*/
int bup_regress_dma ()
{
	int flag;
	UINT32 data = 0x12345678;
#ifdef CO_20
	int LoopCnt = 7;
#else
	int LoopCnt = 3;
#endif
	int oldP = printDiags;

	while (LoopCnt > 0)
	{
		printDiags = 0;
		flag = bup_SdramDma (5001, data, 0,LoopCnt);
		if (flag)
		{
			break;
		}
		LoopCnt--;
		data = data++;
	}
	printDiags = oldP;
	return flag;

}
/*--------------------------------------------------------*/
int bup_sdram_dma_1_100bytes ()
{
	int NumBytes = 0;
	int i = 0;
	UINT32 StartData = 0x55aa6699;
	UINT32 CCR;
	int flag = 0;
	UINT32 data1 = 0;
	int test_fail = 0;

	// DMA from 0x40000000 to 0x40000100
	for (NumBytes=1; NumBytes<=100; NumBytes++)
	{
		bup_WriteSdramCO (0x40000000, NumBytes, StartData);  /* first write SDRAM "i" locations*/
		testPIOWrite (bup_bme,0xe0030040,0x80000000);	 /*set software DMA request*/
		testPIOWrite (bup_bme,0xe0030080,0x40000000);	 /*set source address*/
		testPIOWrite (bup_bme,0xe00300c0,0x40000100);	 /*set dest address*/
		CCR = ((NumBytes-1) << 16) | 0x1001;
		testPIOWrite (bup_bme,0xe0030000,CCR);  /*Load DMA ccr register to start DMA*/
		iposTaskDelay(10);
		while (!(data1 & 0x100))  /*polling for DMA done bit*/
		{
			iposTaskDelay(10);
			data1 = testPIORead1 (bup_bme,0xe0030000);
			i++;
			if (i == 300)
			{
				i = 0;
				printf ("**** Time out in DMA done polling, Numbytes = %d ****\n",NumBytes);
				break;
			}
		}

		// DMA from 0x40000100 to 0x40000200
		testPIOWrite (bup_bme,0xe0030040,0x80000000);	 /*set software DMA request*/
		testPIOWrite (bup_bme,0xe0030080,0x40000100);	 /*set source address*/
		testPIOWrite (bup_bme,0xe00300c0,0x40000200);	 /*set dest address*/
		CCR = ((NumBytes-1) << 16) | 0x1001;
		testPIOWrite (bup_bme,0xe0030000,CCR);  /*Load DMA ccr register to start DMA*/
		iposTaskDelay(10);
		while (!(data1 & 0x100))  /*polling for DMA done bit*/
		{
			iposTaskDelay(10);
			data1 = testPIORead1 (bup_bme,0xe0030000);
			i++;
			if (i == 300)
			{
				i = 0;
				printf ("**** Time out in DMA done polling, Numbytes = %d ****\n",NumBytes);
				break;
			}
		}
		// Read back the data from 0x40000200
		flag = bup_ReadSdramCO (0x40000200,NumBytes,StartData);
		if (flag)
		{
			test_fail = 1;
			break;
		}
		StartData = StartData + 0x1;
	}
	return test_fail;
}
/*--------------------------------------------------------*/
int bup_dmadebug ()
{
	int i = 0;
	UINT32 data1 = 0x0;
	UINT32 CcrReg;
	int flag = 0;
	int NumBytes = 255;

	testPIOWrite (bup_bme,0xe0060300,0x47);  //bfifo cbft_a
	testPIOWrite (bup_bme,0xe0060400,0x00);  //bfifo cbft_b

	bup_WriteSdramCO (0x40000000,1000,0x11223344);

	//dma from sdram to bfifo interleave
	testPIOWrite (bup_bme,0xe0030040,0x80000000);	 /*set software DMA request*/
	testPIOWrite (bup_bme,0xe0030080,0x40000000);	 /*set source address*/
	testPIOWrite (bup_bme,0xe00300c0,0xc5000000);	 /*set dest address*/
	CcrReg = 0x00001011 | (NumBytes << 16);
	testPIOWrite (bup_bme,0xe0030000,CcrReg);	 /*Load DMA ccr register to start DMA*/
	iposTaskDelay(10);
	while (!(data1 & 0x100))  /*polling for DMA done bit*/
	{
		iposTaskDelay(100);
		data1 = testPIORead1 (bup_bme,0xe0030000);
		i++;
		if (i == 10)
		{
			i = 0;
			printf ("********* Time out in DMA done polling1 ********\n");
			break;
		}
	}
	//dma from bfifo interleave to sdram back
	testPIOWrite (bup_bme,0xe0030040,0x80000000);	 /*set software DMA request*/
	testPIOWrite (bup_bme,0xe0030080,0xc5000000);	 /*set source address*/
	testPIOWrite (bup_bme,0xe00300c0,0x40008000);	 /*set dest address*/
	CcrReg = 0x00001011 | (NumBytes << 16);
	testPIOWrite (bup_bme,0xe0030000,CcrReg);	 /*Load DMA ccr register to start DMA*/
	iposTaskDelay(10);
	while (!(data1 & 0x100))  /*polling for DMA done bit*/
	{
		iposTaskDelay(100);
		data1 = testPIORead1 (bup_bme,0xe0030000);
		i++;
		if (i == 10)
		{
			i = 0;
			printf ("********* Time out in DMA done polling2 ********\n");
			break;
		}
	}

	flag = bup_ReadSdramCO (0x40008000,NumBytes,0x11223344);
	return flag;
}
//----------------------------------------------------------------------------
void bup_write_read_whole_memory ()	  //present memory on board : 16 Mbytes (128 Mbit)
{
	UINT32 data, addr;
	UINT32 EvenData = 0xaaaaaaaa;
	UINT32 OddData = 0x55555555;
	int test_fail = 0;
	int i;
	UINT32 ExpData;
	int MemSize = 4194304;

	printf("\tPlease be patient for ~10 minutes .......\n");

	//write whole SDRAM
	for (i=0;i<MemSize; i++)
	{
		if (i%2 == 0)	  //even address
		{
			data = EvenData;
			EvenData = EvenData + 1;
		}
		else
		{
			data = OddData;
			OddData = OddData + 1;
		}
		addr = (i*4 | 0x40000000);
		tpw (bup_bme, addr, data);
		if ((addr % 10240) == 0)
		{
			printf ("w");
			iposTaskDelay (2);
		}
	}

	//read whole SDRAM
	EvenData = 0xaaaaaaaa;
	OddData = 0x55555555;

	for (i=0;i<MemSize; i++)
	{
		if (i%2 == 0)	  //even address
		{
			ExpData = EvenData;
			EvenData = EvenData + 1;
		}
		else
		{
			ExpData = OddData;
			OddData = OddData + 1;
		}

		addr = (i*4 | 0x40000000);
		data = testPIORead1 (bup_bme, addr);
#ifdef DEBUG_MSG
		printf("\ttpr addr: 0x%x, data: 0x%x\n", addr, data);
#endif
		if (data != ExpData)
		{
			test_fail = 1;
			break;
		}
		if ((addr % 10240) == 0)
		{
			printf ("r");
			iposTaskDelay (2);
		}

	}

	printf ("\n"); 
	printf ("******************************************************\n"); 
	if (test_fail)
	{
		printf ("******************************************************\n"); 
		printf ("\tSDRAM test FAILED @Addr:0x%x  Data:0x%x  Exp data:0x%x\n",addr,data,ExpData);
		printf ("******************************************************\n"); 
	}
	else if (printDiags)
	{
		printf ("******************************************************\n"); 
		printf ("\tSDRAM whole memory wirte/read test PASSED\n"); 
		printf ("******************************************************\n"); 
	}
}
//---------------------------------------------------------------
void bup_SdramRandom ()
{
	int i;
	int RandData;
	int testfail=0;
	unsigned int CtrlData;
	int ba;
	int Loop, oldP;


	printf ("\tSetting random EMI Control values:\n");
	for (i=0; i<10; i++)
	{
		bmeHwResetApi (1);	//reset CO fpga
		iposTaskDelay (50);

		CtrlData = rand ();
//		ba = (CtrlData & 0x7000) >> 12;	 //take 3 bits for bank interleaving
		ba = (CtrlData & 0x7000) >> 13;	 //take 3 bits for bank interleaving
//		CtrlData = CtrlData & 0x97e | 0x100;
		CtrlData = CtrlData & 0x107e;
		if (printDiags) printf ("\t%d. EMI_CTRL: 0x%x  \tBank Interleave: 0x%x",i,CtrlData,ba);
//		bup_InitSdramCORand(CtrlData, ba);
		InitSdramCPE4Rand(CtrlData, ba);
		iposTaskDelay(10);
		RandData = rand ();
		if (printDiags)
			printf ("\tStart Data: 0x%x\n",RandData);
		
		oldP = printDiags; printDiags = 1;
		testfail = bup_SdramDma (8191, RandData,0,0);
		printDiags = oldP;

//	printf (".");
		if (testfail)
			break;
	}
	if (testfail)
	{
		printf ("\n******************************************************\n"); 
		printf ("\tSDRAM random test FAILED\n");
		printf("%d.EMI control register: 0x%x \t Bank Interleaving: 0x%x\n",Loop,CtrlData,ba);
		printf ("******************************************************\n");
	}
	else
	{
		if (printDiags)
		{
			printf ("\n******************************************************\n"); 
			printf ("\tSDRAM random test PASSED\n");
			printf ("******************************************************\n");
		}
	}
}
//-------------------------------------------------------------------
void bup_SdramBurstRefresh ()
{
	testPIOWrite (bup_bme,0xe0038000,0x58);
	testPIOWrite (bup_bme,0xe0038020,0x0);
	testPIOWrite (bup_bme,0xe0038004,0x50000f2e);	  // 6 refreshes every 93 us, for 31Mhz memclk 
	testPIOWrite (bup_bme,0xe003800c,0x00000000);
	testPIOWrite (bup_bme,0xe0038008,0x00000000);
	testPIOWrite (bup_bme,0xe0038008,0x00000000);
	testPIOWrite (bup_bme,0xe0038010,0x00000000);

	bup_WriteSdramCO (0x40000000,8000,0x11223344);	//write 8000 bytes to memory

	printf ("**********************************************************\n"); 
	printf("     Please read back and verify the data next day by,\n");
	printf("     SdramVerifyCO (0x40000000,8000,0x11223344)\n");
	printf ("**********************************************************\n"); 
}
/*--------------------------------------------------------*/
void bup_SdramVerifyCO (int StartAddr, int NumBytes, UINT32 StartData)
{
	int testfail = 0;

	testfail = bup_ReadSdramCO (StartAddr,NumBytes,StartData);
	if (!testfail)
	{
		printf ("****************************************************\n"); 
		printf ("\tSDRAM Data read/compare OK .........\n");
		printf ("****************************************************\n"); 
	}
	else if (printDiags)
	{
		printf ("****************************************************\n"); 
		printf ("\tSDRAM Data compare ERROR .........\n");
		printf ("****************************************************\n"); 
	}
}
#endif
