#include "Page0.h"
#include "PalmChip.h"
#include "v_task.h"
#include "p_dsp.h"

//Diagnostic test
#ifdef VER_IPH_E00            //difine word for LCDplay

#define	TEST_START_MENU		0
#define	TEST_MAIN_MENU		1
#define	TEST_AC97_MENU		2
#define	TEST_EXIT_MODE		3

static BOOLEAN	_bHookTest = FALSE;
static BOOLEAN	_bTestKeyMode = FALSE;
static BOOLEAN	_bTestKeyBuf = FALSE;
static BOOLEAN	_bHandsetOK = FALSE;
static BOOLEAN	_bAudioMode;
static XCHAR	_iTestMode = TEST_START_MENU;
static XCHAR	_iKeyTotalInput = 0;
static XCHAR	Key_iBuf[KEY_TOTAL];

CCHAR _cFivesStr[] = "555555555555555555555555";
CCHAR _cAsStr[] = "AAAAAAAAAAAAAAAAAAAAAAAA";
CCHAR _cExitStr[] = "Press *2 TO EXIT";
CCHAR _cTestModeStr[] = "KEYPADE TEST MODE";
#ifndef VER_IPH_E00_2G
CCHAR _cTestStr[] = "INPUT KEY TO TEST MODE";
CCHAR _cTestMenuStr[] = "1.AUTO 2.MANUAL 3.RESET";
CCHAR _cMenu1Str[] = "1.KEY 2.SDRAM 3.LCD&LED";
CCHAR _cMenu2Str[] = "4.AC97 5.RETURN";
CCHAR _cAnaDigStr[] = "1.Analog 2.Digitize";
CCHAR _cReturnStr[] = "3.Return";
#else
CCHAR _cTestStr[] = "1.AUTO 2.MANUAL";
CCHAR _cTestMenuStr[] = "3.RESET";
CCHAR _cMenu1Str[] = "1.KB 2.RAM 3.LCD";
CCHAR _cMenu2Str[] = "4.AC97 5.Exit";
CCHAR _cAnaDigStr[] = "1.Analog";
CCHAR _cReturnStr[] = "2.Digital 3.Exit";
#endif
#endif               

extern BOOLEAN Dtmf_bTesting;

void _OnImpossibleKey()
{
	// Call all un-called functions here
	Cam_LedOff(Sys_cOptions[0]);
	DebugCString((PCCHAR)"");
	p_getKeyId(0);
	GetHardwareVersion();
	GetSoftwareVersion();
	IsBroadcastIP((PXCHAR)0);
	IsFunctionMode();
	KeypadBackspace();
#ifdef VER_IPH_E00
	L3ClockBlink();
	L3ModeOff();
#endif
	OutputPXCHAR((PXCHAR)1, 0);
	PPPoEDisconnect();
	ProxyGetLocalIP((PXCHAR)0);
	Run_47Mhz();
	SdramCopyData(0, (PXCHAR)0);
	SdramCopyData_0(0, (PXCHAR)0);
	SdramSaveData(0, (PXCHAR)0, 0);
	SdramUpdateFlagByte(0, 0);
#ifdef _USE_FXS_AG1170
	SlicActivePolarityReversal();
	SlicHandleTimer(0);
#endif
#ifdef _USE_FXS_AM79R70
	SlicActivePRMode();
#endif
#ifdef _USE_FXS
	SlicRingHandleTimer(0);
#endif
	SoloFileGetSize();
	SoloFileIsRunning();
	SoloFileSetLimit(0);
	TaskWaitPacket();
	TcbConnected(0);
	TcpOpen((PXCHAR)0, 0, 0);
	TcpSendClose(0);
	UdpSetTos(0, 0);
#ifdef _USE_FAKE_FXO
	DualModeStartup();
	DualModeHandleTimer();
	CheckDualModePrefix();
	CheckDualModeStatus();
#endif
}

// public functions
UCHAR KeypadInitialize()
{
	DCHAR iKey;

	// key matrix PIO 0, 1, 2, 16
    XBYTE[IO_LO_INTEN] |= 0x07;			
	XBYTE[IO_LO_EDGE] |= 0x07;
    XBYTE[IO_HHI_INTEN] = 1;			
	XBYTE[IO_HHI_EDGE] = 1;

	XBYTE[INT_ENABLE] |= INT_MASK_KEY;	// Enable keypad interrupt

	XBYTE[KEY_DOUT] = KEYPAD_COLUMN;
	XBYTE[KEY_ENABLE] = KEYPAD_COLUMN;			// drive 4-bit of keyboard 
	iKey = XBYTE[KEY_DIN] & KEYPAD_ROW;			// read row 
	XBYTE[KEY_ENABLE] = KEYPAD_ROW;				// switch to read column 
	iKey += XBYTE[KEY_DIN] & KEYPAD_COLUMN;		// read column 
	XBYTE[KEY_ENABLE] = KEYPAD_COLUMN;			// drive 4-bit of keyboard 
	XBYTE[KEY_INTEN] = KEYPAD_ROW;				// enable 3-bit iSelection detect 
	XBYTE[KEY_EDGE] = KEYPAD_ROW;				// all edge detect keys 
	return iKey;
}

void _RunTest()
{
	DCHAR iCommand, iSelection, iLen;

	iLen = p_strlen_x(Key_pBuf);
	iCommand = Key_pBuf[iLen-3] - '0';
	if (iCommand > 9) return;
	iSelection = Key_pBuf[iLen-1] - '0';
	if (iSelection > 9) return;

	KeypadClear();
	switch (iCommand)
	{
	case 0:		// ac97 loop test
		Ac97CodecTest(iSelection);
		break;
	case 3:	// begin dsp encode test
		DspEncodeFile(iSelection);
		break;
	case 4:	// begin dsp decode loop test
		DspDecodeFile(iSelection);
		break;
	case 5:
		SdramTest(iSelection);
		break;
	case 6:		// set ac97 volume
		Ac97Test(iSelection);
		break;
	case 8:
		SysTest(iSelection);
		break;
	case 9:
		SysSetMode(iSelection);
		break;
	}
}  

//Diagnostic test
#ifdef VER_IPH_E00

#if defined E00_NEW_HW || defined VER_IPH_E00_2G
void L3Led_Mute_On()
{
	L3ClockOff();
}	
void L3Led_Mute_Off()
{
	L3ClockOn();
}	
void L3Led_Spk_On()
{
	L3DataOff();
}	
void L3Led_Spk_Off()
{
	L3DataOn();
}
#endif	// E00_NEW_HW

void _TestPressedKey()
{
	DCHAR i;

	for (i = 0; i < _iKeyTotalInput; i ++)   
	{	//test different key inputs in key buffer
		if (Key_iBuf[i] == Key_iBuf[_iKeyTotalInput])
		{
			break;
		}
	}
	
	if (i == _iKeyTotalInput)
	{
		_iKeyTotalInput ++;
	}
}

void _IfPressAllKeys()
{
	if (_iKeyTotalInput == KEY_TOTAL && _bHandsetOK)
	{
		//if all key pads and function keys pressed -> start SDRAM test
		SdramTest(0);
	}
}

void _TurnAllLed(BOOLEAN bType)
{
	if (bType)		// Turn on
	{
#if defined E00_NEW_HW || defined VER_IPH_E00_2G
		L3Led_Spk_On();
		L3Led_Mute_On();
#else
		Led_On(MUTE_LIGHT);
		Led_On(SPK_LIGHT);
#endif
		Led_On(NORMAL_LIGHT);
		Led_On(SECOND_LIGHT);
		Led_On(KEYPAD_LIGHT);
	}
	else			// Turn off
	{
#if defined E00_NEW_HW || defined VER_IPH_E00_2G
		L3Led_Spk_Off();
		L3Led_Mute_Off();
#else
		Led_Off(MUTE_LIGHT);
		Led_Off(SPK_LIGHT);
#endif
		Led_Off(NORMAL_LIGHT);
		Led_Off(SECOND_LIGHT);
		Led_Off(KEYPAD_LIGHT);
	}
}

void _WaitFor2S()
{
	SysSleep1Second();
	_TurnAllLed(FALSE);
	DisplayInitialize();
	SysSleep1Second();
}

void _LcdLedTest()
{
	_WaitFor2S();
	
	// Display All As
	_TurnAllLed(TRUE);
	DisplayString((PCCHAR)" ", 0);
//	DtmfPlayKey('#');			// Play tone
	DisplayString((PCCHAR)_cAsStr, 0);
	DisplayString((PCCHAR)_cAsStr, 1);

	_WaitFor2S();

	// Displayy All 5s
	_TurnAllLed(TRUE);
//	DtmfPlayKey('#');			// Play tone
	DisplayString((PCCHAR)_cFivesStr, 0);
	DisplayString((PCCHAR)_cFivesStr, 1);
	
	_WaitFor2S();
}
#endif		 //iPH-E00 Diagnostic Test
		
void HandleNumberKeys()
{
	DCHAR iLen;

	iLen = p_strlen_x(Key_pBuf);

	if (iLen == DISPLAY_MAX_CHAR)
	{
		iLen = 0;
	}
	Key_pBuf[iLen] = Key_iCurrentID;
	iLen ++;
	Key_pBuf[iLen] = 0;

#ifndef VER_IPH_E00
	DisplayLine(Key_pBuf, 0);
#endif

	if (iLen >= 4)
	{
		if (Key_pBuf[iLen-4] == '#' && Key_pBuf[iLen-2] == '*')
		{
#ifdef _USE_FXS
			Ac97Stop();
			SysSleep(20000);
#endif
			_RunTest();
		}
	}

#ifdef VER_IPH_E00
	_TurnAllLed(FALSE);
	if (_iTestMode == TEST_START_MENU)					//Start Menu
	{
		switch(Key_iCurrentID)
		{
		case '1':										//Auto Test Mode for LCD, Keypad, and SDRAM
			_LcdLedTest();
			KeypadClear();							//cler key buffer
			DisplayString((PCCHAR)"KEYPAD TEST MODE", 0);
#ifndef VER_IPH_E00_2G
			DisplayString((PCCHAR)"Press any Key to start", 1);
#else
			DisplayString((PCCHAR)"Press any Key", 1);
#endif
			_bTestKeyMode = TRUE;						//Show Keypad number to LCDplay
			_bHookTest = TRUE;
			_bTestKeyBuf = TRUE;
			_iTestMode = TEST_EXIT_MODE;
			break;

		case '2':										//manual
			_iTestMode = TEST_MAIN_MENU;
			DisplayString((PCCHAR)_cMenu1Str, 0);
			DisplayString((PCCHAR)_cMenu2Str, 1);
			break;

		case '3':
			SysSetMode(0);								//reset page0
			break;
		}
	}
	else if (_iTestMode == TEST_MAIN_MENU)				//Main Menu
	{
		switch(Key_iCurrentID)
		{
		case '1':										//KeyPad manual test mode
			KeypadClear();							//cler buffer
			_iTestMode = TEST_EXIT_MODE;
			_bTestKeyMode = TRUE;
			_bHookTest = TRUE;
			DisplayString((PCCHAR)_cTestModeStr, 0);
			DisplayString((PCCHAR)_cExitStr, 1);
			break;

		case '2':										//Sdram Test mode
			SdramTest(0);
			break;

		case '3':										//Lcd and Led Test mode
			_LcdLedTest();
			DisplayString((PCCHAR)_cMenu1Str, 0);
			DisplayString((PCCHAR)_cMenu2Str, 1);
			break;

		case '4':										//AC97 test mode
			_iTestMode = TEST_AC97_MENU;
			DisplayString((PCCHAR)_cAnaDigStr, 0);
			DisplayString((PCCHAR)_cReturnStr, 1);
			break;

		case '5':										//return to start menu
			_iTestMode = TEST_START_MENU;
			DisplayString((PCCHAR)_cTestStr, 0);
			DisplayString((PCCHAR)_cTestMenuStr, 1);
			break;
		}
	}
	else if (_iTestMode == TEST_AC97_MENU)				//AC97 test mode
	{
		switch(Key_iCurrentID)
		{
		case '1':										//Analog mode
			Ac97Test(0);								//Ac97 analog loop-back
			_bHookTest = TRUE;							//Hook Test mode ON
			_bAudioMode = FALSE; 						//ANALOG
			_iTestMode = TEST_EXIT_MODE;
#ifndef VER_IPH_E00_2G
			DisplayString((PCCHAR)"Analog Audio Test", 0);
#else
			DisplayString((PCCHAR)"Analog Test", 0);
#endif
			DisplayString((PCCHAR)_cExitStr, 1);
			break;

		case '2':										//Digitize mode
			Ac97CodecTest(1);							//DSP G.711u-law loop-back
			_bHookTest = TRUE;							//Hook Test mode ON
			_bAudioMode = TRUE;							//DIGITIZE
			_iTestMode = TEST_EXIT_MODE;
#ifndef VER_IPH_E00_2G
			DisplayString((PCCHAR)"Digitize Audio Test", 0);
#else
			DisplayString((PCCHAR)"Digitize Test", 0);
#endif
			DisplayString((PCCHAR)_cExitStr, 1);
			break;

		case '3':										//Return to main menu
			_iTestMode = TEST_MAIN_MENU;
			DisplayString((PCCHAR)_cMenu1Str, 0);
			DisplayString((PCCHAR)_cMenu2Str, 1);
			break;
		}
	}
	else												//TEST_EXIT_MODE
	{
		if(_bTestKeyMode)								//key mode test
		{
			DisplayLine(Key_pBuf, 1);
			if (_bTestKeyBuf)							//AUTO_KEY test
			{
				DisplayString((PCCHAR)_cTestModeStr, 0);
				//AUTO Test mode detect input KEY = 35 KEYPAD
				Key_iBuf[_iKeyTotalInput]= Key_iCurrentID;
				_TestPressedKey();
				_IfPressAllKeys();
			}
			else										//MANUAL_KEY test
			{
				DisplayString((PCCHAR)_cExitStr, 0);
				if(Key_pBuf[iLen-1] =='2' && Key_pBuf[iLen-2] == '*')
				{	//input '*2' to exit to main menu
					_iTestMode = TEST_MAIN_MENU;
					_bTestKeyMode = FALSE;
					_bHookTest = FALSE;
					DisplayString((PCCHAR)_cMenu1Str, 0);
					DisplayString((PCCHAR)_cMenu2Str, 1);
				}
			}
		}
		else											//AC97 mode test
		{
			if (Key_pBuf[iLen-1] =='2' && Key_pBuf[iLen-2] == '*')
			{
				if(_bAudioMode)							//DIGITIZE
				{
					Ac97CodecTest(7);					//Digitize loop-back off
				}
				else									//ANALOG
				{
					Ac97Test(1);						//Analog loop-back off
				}
				_bHookTest = FALSE;
				_iTestMode = TEST_AC97_MENU;
				DisplayString((PCCHAR)_cAnaDigStr, 0);
				DisplayString((PCCHAR)_cReturnStr, 1);
			}
		}
	}
#endif		//VER_IPH_E00
}

void OnHandset()
{
	Ac97OnHandsetChange();

#ifdef VER_IPH_E00
	if (!_bHookTest)
	{
		return;
	}

	_bHandsetOK = TRUE;
	_IfPressAllKeys();
	SysSleep1Second();
#endif

	if (PIO_bHandsetUp)
	{
		if (PIO_bHandFree)
		{
			PIO_bHandFree = FALSE;
		}
		DisplayString(g_cHandsetUp, 1);
#ifdef _USE_FXS_AM79R70
		SlicActiveMode();
#endif
#ifdef _USE_FXS
		if (!Sys_bLoadDefault)
		{	// start detecting keypad
			Task_bConnected = FALSE;
			Ac97_iDtmfDuration = 0;
			Ac97_iDtmfCode = DTMF_SIGNAL_QUIET;
			Sys_iDtmfType = DTMF_INBAND_AUDIO;
			Ac97SetInputSampleRate(TRUE);						//8K bps input
			Dsp_iType = CODEC_G711U;
			Ac97Start();
		}
#endif
	}
	else
	{
		DisplayString(g_cHandsetDown, 1);
#ifdef _USE_FXS_AM79R70
		SlicStandbyMode();
#endif
#ifdef _USE_FXS
		Ac97Stop();
#endif
	}
	KeypadClear();
#ifdef VER_IPH_E00
	if (!_bTestKeyMode)
	{
		DisplayString((PCCHAR)_cExitStr, 1);
	}
#endif
}

void HandleFunctionKeys()
{
#ifdef VER_IPH_E00
	if (!_bTestKeyMode)
	{
		return;
	}
	
	_TurnAllLed(FALSE);
	
	Key_iBuf[_iKeyTotalInput]= Key_iCurrentID;
	_TestPressedKey();
	_IfPressAllKeys();

	DisplayString((PCCHAR)_cTestModeStr, 0);			//show key test
#ifndef VER_IPH_E00_2G
	switch(Key_iCurrentID)
	{
	case 'O':			//v-
		DisplayString(g_cVolMinus, 1);
		break;
	case 'P':			//V+
		DisplayString(g_cVolPlus, 1);
		break;
	case 'N':			//SPK
#ifdef E00_NEW_HW
		L3Led_Spk_On();
#else
		Led_On(SPK_LIGHT);
#endif
		DisplayString((PCCHAR)"Handfree", 1);
		break;
	case 'M':			//Mute
#ifdef E00_NEW_HW
		L3Led_Mute_On();
#else
		Led_On(MUTE_LIGHT);
#endif
 		DisplayString((PCCHAR)"Mute", 1);
		break;
	case 'A':			//Redial
		DisplayString(g_cRedial, 1);
		break;
	case 'B':			//Speed Number
		DisplayString((PCCHAR)"SPD Num", 1);
		break;
	case 'C':			//Get Balance
		DisplayString((PCCHAR)"Balance", 1);
		break;
	case 'I':			//Power Status
		DisplayString((PCCHAR)"PWR", 1);
		break;
	case 'J':			//Call Record
		Led_On(NORMAL_LIGHT);
		DisplayString((PCCHAR)"Call REC", 1);
		break;
	case 'K':			//Voice Message
		Led_On(SECOND_LIGHT);
		DisplayString((PCCHAR)"Voice MSG", 1);
		break;
	case 'L':			//Ethernet Status
		DisplayString((PCCHAR)"Ethernet", 1);
		break;
	case 'E':			//Function Key 7
		DisplayString((PCCHAR)"FUN7", 1);
		break;
	case 'F':			//Function Key 6
		DisplayString((PCCHAR)"FUN6", 1);
		break;
	case 'G':			//Function Key 5
		DisplayString((PCCHAR)"FUN5", 1);
		break;
	case 'H':			//Function Key 4
		DisplayString((PCCHAR)"FUN4", 1);
		break;
	case 'Q':			// 1 1111 000			SK1
		DisplayString((PCCHAR)"SK1", 1);
		break;
	case 'R':			// 0 1111 001			SK2
		DisplayString((PCCHAR)"SK2", 1);
		break;
	case 'S':			// 0 1111 010			SK3
		DisplayString((PCCHAR)"SK3", 1);
		break;
	case 'T':			// 0 1111 100			SK4
		DisplayString((PCCHAR)"SK4", 1);
		break;
	case 'W':			// 0 1111 010			Function Key 1
		DisplayString((PCCHAR)"FUN1", 1);
		break;
	case 'V':			// 0 1111 001			Function Key 2
		DisplayString((PCCHAR)"FUN2", 1);
		break;
	case 'U':			// 1 0111 000			Function Key 3
		DisplayString((PCCHAR)"FUN3", 1);
		break;
	}
#else
	switch(Key_iCurrentID)
	{
	case 'O':			//Flash
		DisplayString((PCCHAR)"Flash", 1);
		break;
	case 'P':			//IP/TELNUM
		DisplayString((PCCHAR)"IP/TELNUM", 1);
		break;
	case 'M':			//SPK
 		DisplayString((PCCHAR)"Speaker", 1);
		break;
	case 'B':			//Hold
		DisplayString((PCCHAR)"Hold", 1);
		break;
	case 'I':			//v-
		DisplayString(g_cVolMinus, 1);
		break;
	case 'J':			//V+
		DisplayString(g_cVolPlus, 1);
		break;
	case 'K':			//Enter
		DisplayString((PCCHAR)"Enter", 1);
		break;
	case 'L':			//SP DIAL
		DisplayString((PCCHAR)"SP DIAL", 1);
		break;
	case 'E':			//Service
		DisplayString((PCCHAR)"Service", 1);
		break;
	case 'F':			//Redial
		DisplayString(g_cRedial, 1);
		break;
	case 'G':			//Balance
		DisplayString((PCCHAR)"Balance", 1);
		break;
	case 'H':			//Call Log
		DisplayString((PCCHAR)"Call Log", 1);
		break;
	}	
#endif
#else
	XCHAR pBuf[2];

	pBuf[0] = Key_iCurrentID;
	pBuf[1] = 0;
	DisplayLine(pBuf, 0);
#endif
	if (Key_iCurrentID == 'X')
	{
		_OnImpossibleKey();
	}
	KeypadClear();
}

void OnHookFlash()
{
}