#include "Page0.h"
#include "PalmChip.h"

void SdramInitialize()
{
	DCHAR i;

	XBYTE[HANDSP_PIN_MUX] = 0;
//	XBYTE[SDRAM_INIT] = 0x8a;			// for 16M Bytes, 16 bits SDRAM
//	XBYTE[SDRAM_INIT] = 0xab;			// for 8M Bytes, 8 bits SDRAM
//	XBYTE[SDRAM_INIT] = 0x81;			// for 8M Bytes, 16 bits SDRAM
	XBYTE[SDRAM_INIT] = 0x80;			// for 2M Bytes, 16 bits SDRAM

//	XBYTE[SDRAM_DMA_MTL] = 0x10;		// at least transfer 16 dword during a DMA
	XBYTE[SDRAM_REFL] = 0x80;			// set "safe" sdram refresh rate 
	XBYTE[SDRAM_REFH] = 0x00;

	XBYTE[SDRAM_WID0L] = 0;
	XBYTE[SDRAM_WID0H] = 0;

	// DMA default between 8032 and SDRAM
	XBYTE[SRAM_CON_CH1ADDRH] = 0;
	XBYTE[DMA9_Y1] = 0;
	XBYTE[DMA9_HIGH] = 0;

	// DMA default between ac97 and SDRAM
	XBYTE[DMA7_Y1] = 0;		// Input
	XBYTE[DMA6_Y1] = 0;		// Output

	SdramClearDataCache();
	// call record
	for (i = 0x20; i < 0x2f; i += 2)
	{
		sdram_write(OPTIONS_SDRAM_HI, i, SRAM_DMA_DWORD);
	}
	for (i = 254; i >= 240; i -= 2)
	{
		sdram_write(AC97_IN_SDRAM_HI, i, SRAM_DMA_DWORD);
		sdram_write(AC97_OUT_SDRAM_HI, i, SRAM_DMA_DWORD);
	}
	for (i = 0; i < 128; i += 2)
	{
		sdram_write(DSP_OUTPUT_SDRAM_HI, i, SRAM_DMA_DWORD);
		sdram_write(DSP_INPUT_SDRAM_HI, i, SRAM_DMA_DWORD);
	}

#if defined AM29LV008B || defined MX29LV008B
	// load settings and quick dial
	SdramLoadData(Sys_cOptions, 0x0000, OPTIONS_TOTAL_LEN);
#endif
}

void SdramStartup()
{
	SdramReadFlags();
	if (XBYTE[Sdram_pDataCache+FLAGS_PAGE3_LOADED] != 1 || 
		(XBYTE[Sdram_pDataCache+FLAGS_PAGE3_RUN] != '3' && XBYTE[Sdram_pDataCache+FLAGS_PAGE3_RUN] != '5'))
	{
		// load default settings
		SdramLoadData(Sys_cSafeOptions, 0x0000, 512);
		p_memcpy_c2x((PXCHAR)(Sdram_pDataCache + FLAGS_PRODUCT_TAG), Sys_cFlags, MAX_TAG_LENGTH);
		Sys_bLoadDefault = TRUE;
	}
	else
	{
		XBYTE[Sdram_pDataCache+FLAGS_PAGE3_LOADED] = 0;
		XBYTE[Sdram_pDataCache+FLAGS_PAGE3_RUN] = 0;
		Sys_bLoadDefault = FALSE;
	}
	SdramWriteFlags();

	SysReadOptions();
	// Options
	Sys_iIPType = IP_TYPE_STATIC;	// Never use DHCP and PPPoE in page0
	// protect account info
	p_memset_x(Sys_pLocalNumber, 0, PHONE_NUMBER_LEN);
	p_memset_x(Sys_pAccount, 0, MAX_ACCOUNT_LEN);
	p_memset_x(Sys_pPin, 0, MAX_PIN_LEN);

	if (Sys_bLoadDefault)
	{
		Udp_iOutputDebug = DEBUG_DISABLE_PRODUCTID;
	}
	else
	{
		Udp_iOutputDebug = DEBUG_LEVEL_INFO;
	}
	SysWriteOptions();
}

void _ConTest()
{
	DCHAR i, j, iTotal;

	// Check read and write
	DisplayString((PCCHAR)"SDRAM_TEST", 0);
#if defined VER_IPH_E00_8B_F || defined VER_IPH_E00_8B_NF
	DisplayString((PCCHAR)"CHECK READ & WRITE", 1);
#else
	DisplayString((PCCHAR)"READ & WRITE", 1);
#endif
#ifdef VER_IPH_E00
	SysSleep1Second();
	SysSleep1Second();
#endif

	iTotal = 32;
	for (i = 0; i < iTotal; i ++)	// 32 for full size 2M bytes test	
	{
		DisplayVal(i, (PCCHAR)"index high", 1);
		UdpDebugUpdate();
		p_memset_x((PXCHAR)Sdram_pDataCache2, i, 256);
		j = 0;
		do
		{
			j -- ;
			p_memset_x((PXCHAR)Sdram_pDataCache, i, 256);
			sdram_write(i, j, SRAM_DMA_HALF_DWORD);
			p_memset_x((PXCHAR)Sdram_pDataCache, 0, 256);
			sdram_read(i, j, SRAM_DMA_HALF_DWORD);
			if (p_memcmp_x2x((PXCHAR)Sdram_pDataCache, (PXCHAR)Sdram_pDataCache2, 256))
			{
				DisplayVal(j, (PCCHAR)"Bad index low", 1);
				DisplayString((PCCHAR)"Test error", 0);
				SysSleep1Second();
			}
		} while (j);
	}

	// Check address
	DisplayString((PCCHAR)"Check address", 0);
	for (i = 0; i < iTotal; i ++)
	{
		p_memset_x((PXCHAR)Sdram_pDataCache2, i, 256);
		sdram_read(i, 0, SRAM_DMA_HALF_DWORD);
		if (p_memcmp_x2x((PXCHAR)Sdram_pDataCache, (PXCHAR)Sdram_pDataCache2, 256))
		{
			DisplayVal(i, (PCCHAR)"Bad address index low", 1);
			DisplayString((PCCHAR)"Test error", 0);
			UdpDebugUpdate();
			SysSleep1Second();
			SysSleep1Second();
		}
	}
	SysSetMode(0);	// Restart since we have modified the sdram in total
}

void SdramMove(UCHAR iDstIndexHigh, UCHAR iSrcIndexHigh)
{
	DCHAR i;

	i = 0;
	do
	{
		i -= 2;
		sdram_read(iSrcIndexHigh, i, SRAM_DMA_DWORD);
		sdram_write(iDstIndexHigh, i, SRAM_DMA_DWORD);
	} while (i);
}

void _OutTest(UCHAR iTestIndexHigh)
{
	DCHAR i, iIndexHigh;

	iIndexHigh = iTestIndexHigh;
	DisplayVal(iIndexHigh, (PCCHAR)"Sdram Out", 1);
	for (i = 0; i < 10; i ++)
	{
		SdramMove(FILE_OUT_SDRAM_HI+i, iIndexHigh);
		iIndexHigh ++;
	}
}

void SysIdle()
{
	DisplayString((PCCHAR)"Sleep test...", 0);
	UdpDebugUpdate();
	while (1)
	{
		SysSleep1Second();
		Led_Blink(SECOND_LIGHT);
	}
}

static CCHAR _cTestIndexHigh[4] = {0, 0, 0x0a, FILE_IN_SDRAM_HI};

void SdramTest(UCHAR iSelectKey)
{
	DCHAR iKey;

	iKey = iSelectKey;
	DisplayString((PCCHAR)"Sdram test", 0);
	switch (iKey)
	{
	case 0:
		_ConTest();
		break;

	case 1:
	case 2:
	case 3:
		_OutTest(_cTestIndexHigh[iKey]);
		break;

	case 5:		// restore default settings
		DefaultSettings();
		OnUpdateOptions();
		break;		

	case 7:
		SwitchPage(9);
		break;

	case 9:
		SysIdle();
		break;
	}
}
