#include <reg52.h>

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

#include "p_rtp.h"

#ifdef MT28F016
static CCHAR _cProgramFlash[] = "MT28F016S5";
#else
static CCHAR _cProgramFlash[] = "OTHERFLASH";
#endif

#ifdef _USE_RS232
extern XCHAR Serial_iInData;
#endif

volatile DCHAR Sys_iWholeSecond = 0;

void _Handle60msTimer()
{
#ifdef VER_IPH_E00
	GKIndicate();
#endif
	if (PIO_iHookFlashTimer)
	{
		PIO_iHookFlashTimer ++;
		if (PIO_iHookFlashTimer > 20)
		{
			// it is hook down event.
			PIO_iHookFlashTimer = 0;
			PIO_bHandsetUp = FALSE;
#ifdef _USE_FAKE_FXO
			CheckDualModeStatus();
#endif
			OnHandset();
		}
	}
}

void main(void)
{
	Led_Off(SECOND_LIGHT);
	Led_On(KEYPAD_LIGHT);
	BootIndication(12);
	SysNormalSpeed();

#ifdef VER_PA168Q
	L3ClockOn();
#endif

	SdramStartup();		// Load settings here
#ifdef VER_IPH_E00
	ModemInitializeStatus();
#endif	
	KeypadStartup();
/*
#ifdef _USE_VLAN
	VLANStartup();
	VLANDisable();
	// just to call to function to make compile successfully, no sense
	VLANRegWrite(3, 22, 5);
	VLANRegRead(3, 22);
#endif
*/
#ifdef _USE_FAKE_FXO
	DualModeStartup();
#endif

	XBYTE[IO_HI_INTEN] &= NE2000_PIO_INT_AND;			// disable ethernet irq, PIO 9
	Modem_bInUse = FALSE;

#ifdef HW_MODEM
	ModemStartup();
#endif

	ControlInitialize();

	sdram_read(SDRAM_CHECK_HI, SDRAM_CHECK_LO, SRAM_DMA_HALF_DWORD);
	Key_iCurrentID = XBYTE[Sdram_pDataCache+SDRAM_CHECK_POS];
	if (Key_iCurrentID)
	{
		BootIndication(13);
//		Ne2000Initialize_Step1();
//		SysSleep(1000000);
		Ne2000Initialize_Step2();
		XBYTE[Sdram_pDataCache+SDRAM_CHECK_POS] = 0;
		sdram_write(SDRAM_CHECK_HI, SDRAM_CHECK_LO, SRAM_DMA_HALF_DWORD);
	}

	if (Key_iCurrentID & SDRAM_CHECK_RING_OK)
	{
		BootIndication(14);
//		SysSleep(1000000);
		BootIndication(15);
	}
	else
	{
		SysHighSpeed();
		ConvertRing();
		SysNormalSpeed();
	}

	for (Key_iCurrentID = 16; Key_iCurrentID < DISPLAY_MAX_CHAR; Key_iCurrentID ++)
	{
		BootIndication(Key_iCurrentID);
	}
	Led_Off(NORMAL_LIGHT);

	Ac97Startup();
	UIStartup();

#ifdef CALL_H323
	H323Startup();
#elif defined CALL_SIP
	SipStartup();
#elif defined CALL_MGCP
	MgcpStartup();
#elif defined CALL_N2P
	N2pStartup();
#elif defined CALL_WP
	WpStartup();
#elif defined CALL_IAX2
	Iax2Startup();
#elif defined CALL_EPN
	EpnStartup();
#endif
	SdramUpdateFlagByte(FLAGS_PROTOCOL, Sys_iProtocol);

#ifdef HW_MODEM
	ModemInit();
#endif

	if (!Modem_bInUse)
	{
		if (!Ne2000Initialize())
		{
			SwitchPage(0);
			DisplayString(_cProgramFlash, 0);
		}
		TcpipInitialize();
	}
	Led_Off(KEYPAD_LIGHT);
	DisplayString(g_cProtocol, 0);
	OutputString(IDS_PAGE1_RUNNING);

//	OutputVal(Key_iCurrentID, IDS_CHECK_POINT_0);
//	UdpDebugUpdate();
	OnCheckHandset();

	switch (Sys_iIPType)
	{
	case IP_TYPE_DHCP:
		DisplayString(g_cDHCP, 0);
		DisplayString(g_cConnecting, 1);
		break;
	case IP_TYPE_PPPOE:
		DisplayString(g_cPPPoE, 0);
		DisplayString(g_cConnecting, 1);
		break;
	}

    while (1)
	{
#ifdef _USE_RS232
		SerialRun();
#endif
		Ac97Run();
		KeypadRun();
#ifdef HW_MODEM
		if (Modem_bInUse)
		{
			ModemRun();
		}
		else
#endif
		{
			Ne2000Run();
		}
		UdpDebugUpdate();
		if (Timer_bIndicated)	// 1 second timer
		{
#ifdef _USE_FAKE_FXO
			DualModeHandleTimer();
#endif
			Task_iTimer ++;
			TcpipHandleTimer();
			UIHandleTimer();
			Timer_bIndicated = FALSE;
		}
		if (Timer_bIndicated2)	// 10, 20 or 30 ms timer, may be missed, not accurate
		{
			// check 60 ms
			if (Sys_bHighSpeed)
			{
				if (Dsp_iType == CODEC_G7231 || Dsp_iType == CODEC_ILBC)
				{
					if (!(Sys_iWholeSecond % 2))
					{
						_Handle60msTimer();
					}
				}
				else if (Dsp_iType == CODEC_GSM610)
				{
					if (!(Sys_iWholeSecond % 3))
					{
						_Handle60msTimer();
					}
				}
				else
				{
					if (!(Sys_iWholeSecond % 6))
					{
						_Handle60msTimer();
					}
				}
			}
			else
			{
				if (!(Sys_iWholeSecond % 3))
				{
					_Handle60msTimer();
				}
			}

#ifdef _USE_FXS_AG1170
			if (Task_bConnecting)
			{
				SlicHandleTimer(Sys_iWholeSecond);
			}
#endif
#ifdef VER_WG2000
                        UIMissedCallIndicate();//judy
#endif
			Timer_bIndicated2 = FALSE;
		}
	}
}

void PalmInterrupt() interrupt 2	// using 2
{
	DCHAR iDPS, iIntVal;
	DCHAR iDPH, iDPL;

	iDPH = DPH1;
	iDPL = DPL1;
	iDPS = DPS;	// Push DPS value
	DPS = 0;

    iIntVal = XBYTE[INT_VALUE];

	if (iIntVal & INT_MASK_DMA)
	{
		Ac97HandleInterrupt();
	}
	if (iIntVal & INT_MASK_DSP)
	{
		XBYTE[INT_CLR] |= INT_MASK_DSP;
		DspHandleInterrupt();
	}
    if (iIntVal & INT_MASK_IO)
	{
#ifdef HW_MODEM
		if (Modem_bInUse)
		{
			if (XBYTE[IO_HI_DIN] & MODEM_PIO_INT_OR)	// PIO 11 for Modem irq
			{
				ModemHandleInterrupt();
			}
			else
			{	// Check PIO 3, 4, 5, 6, 12, 13, 14, 15 key
				IoKeyHandleInterrupt();
			}
		}
		else
#endif
		{
			IoKeyHandleInterrupt();
		}
	}
	if (iIntVal & INT_MASK_KEY)
	{
		KeypadHandleInterrupt();
	}

	DPH1 = iDPH;
	DPL1 = iDPL;
	DPS = iDPS;	// Pop DPS value
}

#ifdef _USE_RS232
void SerialInterrupt() interrupt 4 //using 3
{
	DCHAR iDPS;

	iDPS = DPS;	// Push DPS value
	DPS = 0;
	if (RI)
	{
		Serial_iInData = SBUF0;
		RI = 0;
		SerialHandle();
	}
	DPS = iDPS;	// Pop DPS value
}
#endif

void TaskSendPacket(USHORT iLen, PXCHAR pPacket)
{
#ifdef HW_MODEM
	if (Modem_bInUse)
	{
		if (Modem_bAtCmd)
		{
			ModemSend(iLen, pPacket);
		}
		else
		{
			ModemSendData(iLen, pPacket);
		}
	}
	else
#endif
	{
		Ne2000Send(iLen, pPacket);
	}
}

void OnOutgoingData(UCHAR iLength, PXCHAR pData)
{
	if (Task_bDisconnecting)	return;
	if (Task_bCallHold || Task_bOnHold)		return;
	if (Task_bCallTransfer)	return;
	if (Task_bCaller)
	{
		if (!IsInCall())	return;
	}
	else
	{
		if (Task_iRingType == RING_TYPE_ADVANCED)
		{
			if (!Task_bConnected)	return;
		}
		else
		{
			if (!IsInCall())	return;
		}
	}

#ifdef CALL_H323
	RtpSend(iLength, pData);
#elif defined CALL_SIP
	RtpSend(iLength, pData);
#elif defined CALL_MGCP
	RtpSend(iLength, pData);
#elif defined CALL_N2P
	N2pSendVoice(iLength, pData);
#elif defined CALL_WP
	WpSendVoice(iLength, pData);
#elif defined CALL_IAX2
	Iax2SendVoice(iLength, pData);
#elif defined CALL_EPN
	RtpSend(iLength, pData);
#endif
}


/*
(1.54.004 5111phone iax2)	Program Size: data=125.3 xdata=2228 code=78187
(1.54.004 5111phone mgcp)	Program Size: data=123.6 xdata=2444 code=84442
(1.54.004 5111phone sip)	Program Size: data=126.0 xdata=2389 code=95474
(1.54.004 5111phone h323)	Program Size: data=126.7 xdata=2344 code=111080
(1.54.004 pa168v h323)		Program Size: data=128.2 xdata=2345 code=112520
(1.54.004 pa168v n2p)		Program Size: data=110.2 xdata=2151 code=73306
(1.55.012 pa168v h323)		Program Size: data=128.0 xdata=2307 code=102285
(1.55.012 pa168v sip)		Program Size: data=127.3 xdata=2389 code=96071
(1.56.001 5111phone sip)	Program Size: data=126.0 xdata=2388 code=95294
(1.56.001 pa168v sip)		Program Size: data=127.3 xdata=2389 code=96917
*/
