#include "Page0.h"

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

extern BOOLEAN Ac97_bLoopTest;

static BOOLEAN _bTestG729 = FALSE;

CCHAR cTotalFrames[] = "total frames";
CCHAR cFile[] = "file";
CCHAR cEncoding[] = "encoding...";
CCHAR cDecoding[] = "decoding...";
CCHAR cG723Test[] = "test g.723.1";
CCHAR cG729Test[] = "test g.729";
 
static XSHORT _iEncodeCall, _iDecodeCall;

static XSHORT _iEncodeInputBytes, _iDecodeOutputBytes;
static XCHAR  _iCompressedBytes;

static CSHORT _cDataSize48k[CODEC_NULL] = {960, 2880, 960, 960, 1920, 2880};
static CSHORT _cDataSize8k[CODEC_NULL] = {160, 480, 160, 160, 320, 480};

// wait/nowait bit mask for command queue
#define CMDQ_NOWAIT		0x00
#define CMDQ_WAIT		0x80

void _ZeroSwapMem()	// assure that first 4096 bytes sdram is zero;
{
	// Write all 0 to Dsp DMSwap
	XBYTE[CMDQ_DL] = 0x03;					// Sdram access DM
	XBYTE[CMDQ_DH] = 0x10|CMDQ_WAIT;		// Sdram access DM
	XBYTE[SRAM_DM_CH1ADDRL] = 0;			// DMSwap start address
	XBYTE[SRAM_DM_CH1ADDRH] = 0;			// DMSwap start address
	XBYTE[DMA13_START_ADDR1] = 0;			// Sdram start address
	XBYTE[DMA13_START_ADDR2] = 0;			// Sdram start address
	XBYTE[DMA13_START_ADDR3] = 0;			// Sdram start address
	XBYTE[DMA13_X1] = 0;					// Number of DWORD to transfer
	XBYTE[DMA13_HIGH] = 0x08;				// High bits for number of DWORD to transfer and sdram start address
	XBYTE[CMDQ_DL] = 0;						// Load to DM
	XBYTE[CMDQ_DH] = 0x40|CMDQ_WAIT;		// Load to DM
	XBYTE[CMDQ_DL] = 0x02;					// Dsp access DM
	XBYTE[CMDQ_DH] = 0x10|CMDQ_WAIT;		// Dsp access DM

	// Write all 0 to Dsp PMSwap
	XBYTE[CMDQ_DL] = 0x01;					// Sdram access PM
	XBYTE[CMDQ_DH] = 0x10|CMDQ_WAIT;		// Sdram access PM
	XBYTE[SRAM_PM_CH1ADDRL] = 0;			// PMSwap start address
	XBYTE[SRAM_PM_CH1ADDRH] = 0;			// PMSwap start address
	XBYTE[DMA11_START_ADDR1] = 0;			// Sdram start address
	XBYTE[DMA11_START_ADDR2] = 0;			// Sdram start address
	XBYTE[DMA11_START_ADDR3] = 0;			// Sdram start address
	XBYTE[DMA11_X1] = 0;					// Number of DWORD to transfer, 0 is supposed to be 1024
	XBYTE[DMA11_HIGH] = 0;					// High bits for number of DWORD to transfer and sdram start address
	XBYTE[CMDQ_DL] = 0;						// Load to PM
	XBYTE[CMDQ_DH] = 0x60|CMDQ_WAIT;		// Load to PM
	XBYTE[CMDQ_DL] = 0x00;					// Dsp access PM
	XBYTE[CMDQ_DH] = 0x10|CMDQ_WAIT;		// Dsp access PM
}

void DspInitialize()
{
	XBYTE[DSP_INT_EN] = 0x01;			// enable DSP termination interrupt 
	XBYTE[INT_ENABLE] |= INT_MASK_DSP;	// enable DSP interrupt 
	XBYTE[INT_EDGE] |= INT_MASK_DSP;	// edge trigger since the interrupt from DSP is a narrow pulse 
	XBYTE[SDRAM_DSP_REQ] = 0xaa;		// set DSP request level to 2
//	XBYTE[SDRAM_DSP_REQ] = 0x55;		// set DSP request level to 1

	XBYTE[CMDQ_CS] = 1;					// clear command queue
	XBYTE[CMDQ_DL] = 0x00;				// reset DSP
	XBYTE[CMDQ_DH] = 0x20;				// reset DSP 

	XBYTE[SRAM_DM_PM_CTRL] = 0x87;		// Set SDRAM endian concern, and both PM and DM to single mode
	_ZeroSwapMem();						// zero DMSwap and PMSwap memory
}

void SysTest(UCHAR iSelectKey)
{
	DCHAR iKey;

	iKey = iSelectKey;
	if (iKey)
	{
		SysSetMode(iKey);
		if (_bTestG729)
		{
			G729FullTest();
		}
		else
		{
			G723FullTest();
		}
		SysSetMode(3);
	}
	else
	{
		Led_Blink(KEYPAD_LIGHT);
		if (_bTestG729)
		{
			_bTestG729 = FALSE;
			DisplayString(cG723Test, 0);
		}
		else
		{
			_bTestG729 = TRUE;
			DisplayString(cG729Test, 0);
		}
	}
}

void _DspStartDebug()
{
	switch (Dsp_iType)
	{
	case CODEC_NULL:	// Loop back without codec
		_iCompressedBytes = 160;
#ifndef VER_IPH_E00
		DisplayString((PCCHAR)"filter loop", 0);
#endif
		break;
	case CODEC_G711U:	//G711U
		_iCompressedBytes = 80;
#ifndef VER_IPH_E00
		DisplayString((PCCHAR)"g.711u", 0);
#endif
		break;
	case CODEC_G711A:	//G711A
		_iCompressedBytes = 80;
#ifndef VER_IPH_E00
		DisplayString((PCCHAR)"g.711a", 0);
#endif
		break;
/*	case CODEC_GSM610:	// GSM610
		_iCompressedBytes = 36;
		DisplayString((PCCHAR)"GSM 6.10", 0);
		break;
*/
	case CODEC_G729:	// G729
		_iCompressedBytes = 12;
#ifndef VER_IPH_E00
		DisplayString((PCCHAR)"g.729", 0);
#endif
		break;
	case CODEC_G7231:	//G7231
		_iCompressedBytes = 24;
#ifndef VER_IPH_E00
		DisplayString((PCCHAR)"g.723.1", 0);
#endif
		break;
	default:
		DisplayString(g_cInvalidLabel, 0);
		return;
	}

#ifndef VER_IPH_E00
	DisplayString((PCCHAR)"8k enc", 1);
#endif
	if (Dsp_iType <= CODEC_NULL)
	{
		_iEncodeInputBytes = _cDataSize8k[Dsp_iType];
	}
	else if (Dsp_iType == CODEC_NULL)
	{
		_iEncodeInputBytes = 160;
	}

#ifndef VER_IPH_E00
	DisplayString((PCCHAR)"48k dec", 1);
#endif
	if (Dsp_iType <= CODEC_NULL)
	{
		_iDecodeOutputBytes = _cDataSize48k[Dsp_iType];
	}
	else if (Dsp_iType == CODEC_NULL)
	{
		_iDecodeOutputBytes = 960;
	}
}                              


void DspEncodeFile(UCHAR iKey)
{
	DSHORT i, iFrames, iInputPos, iOutputPos;

	DisplayString((PCCHAR)"Begin dsp encode test", 0);
	_DspStartDebug();
	Dsp_iType = iKey;
//	DspStart(iKey);
	iInputPos = 0;
	iOutputPos = 0;
	iFrames = 0xffff/_iEncodeInputBytes;
	DisplayVal(iFrames, cTotalFrames, 1);
	DisplayString(cEncoding, 0);
	UdpDebugUpdate();
	SysTickBegin();
	for (i = 0; i < iFrames; i ++) /*iFrames*/
	{
		DspWriteDMC(ENC_INPUT_SDRAM_HI, FILE_IN_SDRAM_HI);
		DspWriteDMC(ENC_INPUT_SDRAM_LO, iInputPos);
		DspWriteDMC(ENC_OUTPUT_SDRAM_HI, FILE_OUT_SDRAM_HI);
		DspWriteDMC(ENC_OUTPUT_SDRAM_LO, iOutputPos);
		DspExecuteAndWait(_iEncodeCall);
		iInputPos += _iEncodeInputBytes;
		iOutputPos += _iCompressedBytes;
	}
	SysTickEnd();
}

void DspDecodeFile(UCHAR iKey)
{
	DSHORT i, iFrames, iInputPos, iOutputPos;

	DisplayString((PCCHAR)"Begin dsp decode test", 0);
	UdpDebugUpdate();

	_DspStartDebug();
	Dsp_iType = iKey;
//	DspStart(iKey);
	iInputPos = 0;
	iOutputPos = 0;
	iFrames = 0xffff/_iDecodeOutputBytes;
	DisplayVal(iFrames, cTotalFrames, 1);
	DisplayString(cDecoding, 0);
	SysTickBegin();
	for (i = 0; i < iFrames; i ++)     // iFrames
	{
		DspWriteDMC(DEC_INPUT_SDRAM_HI, FILE_IN_SDRAM_HI);
		DspWriteDMC(DEC_INPUT_SDRAM_LO, iInputPos);
		DspWriteDMC(DEC_OUTPUT_SDRAM_HI, FILE_OUT_SDRAM_HI);
		DspWriteDMC(DEC_OUTPUT_SDRAM_LO, iOutputPos);
		DspExecuteAndWait(_iDecodeCall);
		iInputPos += _iCompressedBytes;
		iOutputPos += _iDecodeOutputBytes;
	}
	SysTickEnd();
}


void OnOutgoingData(UCHAR iLength, PXCHAR pData)
{
	if (Ac97_bLoopTest)
	{
		DspHandleDecodeData(iLength, pData);
	}
	else
	{
		UdpTestSend(pData, iLength);
	}
}

