⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cem847x.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 5 页
字号:
	{		CQuasar__WriteReg(pIDecoder, this->Pio8fDataReg,			((Data? 0x0101:0x0100) << (PIONumber-8)));		CQuasar__WriteReg(pIDecoder, this->Pio8fDirReg,			(0x0101 << (PIONumber-8)));	}	return Q_OK;}/****f* HwLib/IDecoder_ReadPIO * USAGE *	QRESULT IDecoder_ReadPIO(IDecoder* pIDecoder, DWORD PIONumber, DWORD* pData) *	QRESULT CEM840X__ReadPIO(IDecoder* pIDecoder, DWORD PIONumber, DWORD* pData) *	QRESULT CEM847X__ReadPIO(IDecoder* pIDecoder, DWORD PIONumber, DWORD* pData) * DESCRIPTION *	EM840x has 8 input/output pins PIOs *	EM847x has 16 input/output pins PIOs *	IDecoder_ReadPIO sets the direction of pin "PIONumber" to input and reads the pin input. * PARAMETERS *	IN IDecoder* pIDecoder - pointer to the decoder object *	IN DWORD PIONumber - one of PIO0 ... PIO15. *	IN BOOL* pData - poiterto read PIO: TRUE means high level, FALSE means low level for PIO. * RETURN VALUE *	The return value is Q_FAIL if PIONumber is greater then the maximum number of PIOs supported./********************************************************************************************/QRESULT CEM847X__ReadPIO(IDecoder* pIDecoder, DWORD PIONumber, DWORD* pData){	CQuasar *this = (CQuasar*) pIDecoder;	// don't assume that PIO is input	if(PIONumber < 8)	{		CQuasar__WriteReg(pIDecoder, this->Pio07DirReg,			(0x0100 << PIONumber) );		*pData = (CQuasar__ReadReg(pIDecoder, this->Pio07DataReg) & (0x0100 << PIONumber)) ? 1:0;	}	else	{		CQuasar__WriteReg(pIDecoder, this->Pio8fDirReg,			(0x0100 << (PIONumber-8)) );		*pData = (CQuasar__ReadReg(pIDecoder, this->Pio8fDataReg) & (0x0100 << (PIONumber-8))) ? 1:0;	}	QDbgLog((QLOG_TRACE, QDebugLevelTrace, TEXT("   PIO%d read %d"), PIONumber, *pData ));	return Q_OK;}/****f* HwLib/IDecoder_SetDisplayFilter * USAGE *	QRESULT IDecoder_SetDisplayFilter( IDecoder* pIDecoder, BYTE FilterId, BYTE* pData, DWORD dwSize) *	QRESULT CEM847X__SetDisplayFilter( IDecoder* pIDecoder, BYTE FilterId, BYTE* pData, DWORD dwSize) * DESCRIPTION *	IDecoder_SetDisplayFilter - sets the luma and chroma coefficients of the horizontal or vertical filter. * PARAMETERS *	IN IDecoder* pIDecoder - pointer to the decoder object *	IN BYTE FilterId - Selects display filters: *		HorizontalBilinear - not recommended *		Horizontal4tapDefault - recommended for mpeg scaled/not scaled, jpeg scaled *      Horizontal4tapJpg - recommended for jpg not scaled  *		VerticalBilinear - used if width > 1536  *		Vertical2tapDefault - used if width > 1536  *		Vertical4tapDefault - used if width < 1536  *	IN BYTE* pData - pointer to a 2x32 bytes table representing the 2 filter x 32 coefficients for: *		luma, chroma (vertical or horizontal) *	IN DWORD dwSize - size of the buffer sent (32 coefficients = 64 bytes)./********************************************************************************************/QRESULT CEM847X__SetDisplayFilter(IDecoder* pIDecoder, BYTE FilterId, BYTE* pDataIn, DWORD dwSizeIn){	CQuasar *this = (CQuasar*) pIDecoder;	Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ;	DWORD i, HwLumaAddr;	BYTE* pLumaData = Default4TapDisplayFilter;	BYTE* pChromaData = Default4TapDisplayFilter;	DWORD Ctrl1 = IDecoder_ReadDM(pIDecoder, pQ4->DICOM_Control.addr) & ~(BIT5|BIT4);	switch(FilterId)	{	case HorizontalBilinear:		this->HorizontalFilter = HorizontalBilinear;		CQuasar__WriteDM(pIDecoder, pQ4->DICOM_Control.addr,			Ctrl1 | (Q3CTRL1_HORZ_DOWN_FILT_ENABLE | Q4CTRL1_BILIN_HORZ_UP) );		IDecoder_WriteDM(pIDecoder, pQ4->DICOM_UpdateFlag.addr, 1);		IDecoder_WriteDM(pIDecoder, pQ4->DisplayInfo.addr, 0);		return Q_OK;	case CustomHorizontal4tap:		this->HorizontalFilter = CustomHorizontal4tap;		pLumaData = this->Horizontal4tapLumaCoef;		pChromaData = this->Horizontal4tapChromaCoef;		HwLumaAddr = 0x1e90;		Ctrl1 = (Ctrl1 & ~Q4CTRL1_BILIN_HORZ_UP) | Q3CTRL1_HORZ_DOWN_FILT_ENABLE;		IDecoder_WriteDM(pIDecoder, pQ4->DisplayInfo.addr, 0);		break;	case Horizontal4tapDefault:		this->HorizontalFilter = Horizontal4tapDefault;		HwLumaAddr = 0x1e90;		Ctrl1 = (Ctrl1 & ~Q4CTRL1_BILIN_HORZ_UP) | Q3CTRL1_HORZ_DOWN_FILT_ENABLE;		IDecoder_WriteDM(pIDecoder, pQ4->DisplayInfo.addr, 0);		break;	case Horizontal4tapJpg:		this->HorizontalFilter = Horizontal4tapJpg;		pLumaData = DefaultJpg4TapDisplayFilter;		pChromaData = DefaultJpg4TapDisplayFilter;		HwLumaAddr = 0x1e90;		Ctrl1 = (Ctrl1 & ~Q4CTRL1_BILIN_HORZ_UP) | Q3CTRL1_HORZ_DOWN_FILT_ENABLE;		IDecoder_WriteDM(pIDecoder, pQ4->DisplayInfo.addr, 0xD0);		break;	case VerticalBilinear:		this->VerticalFilter = VerticalBilinear;		CQuasar__WriteDM(pIDecoder, pQ4->DICOM_Control.addr,			(Ctrl1 & ~Q4CTRL1_4TAP_VERT_UP_DOWN) | Q4CTRL1_BILIN_VERT_UP_DOWN);		IDecoder_WriteDM(pIDecoder, pQ4->DICOM_UpdateFlag.addr, 1);		return Q_OK;	case CustomVertical2tap:		this->VerticalFilter = CustomVertical2tap;		pLumaData = this->Vertical2tapLumaCoef;		pChromaData = this->Vertical2tapChromaCoef;		HwLumaAddr = 0x1e80;		Ctrl1 = Ctrl1 & ~(Q4CTRL1_4TAP_VERT_UP_DOWN | Q4CTRL1_BILIN_VERT_UP_DOWN);		break;	case Vertical2tapDefault:		this->VerticalFilter = Vertical2tapDefault;		HwLumaAddr = 0x1e80;		Ctrl1 = Ctrl1 & ~(Q4CTRL1_4TAP_VERT_UP_DOWN | Q4CTRL1_BILIN_VERT_UP_DOWN);		break;	case CustomVertical4tap:		this->VerticalFilter = CustomVertical4tap;		pLumaData = this->Vertical4tapLumaCoef;		pChromaData = this->Vertical4tapChromaCoef;		HwLumaAddr = 0x1e80;		Ctrl1 = (Ctrl1 & ~Q4CTRL1_BILIN_VERT_UP_DOWN) | Q4CTRL1_4TAP_VERT_UP_DOWN;		break;	case Vertical4tapDefault:		this->VerticalFilter = Vertical4tapDefault;		HwLumaAddr = 0x1e80;		Ctrl1 = (Ctrl1 & ~Q4CTRL1_BILIN_VERT_UP_DOWN) | Q4CTRL1_4TAP_VERT_UP_DOWN;		break;	default:		return E_NOT_SUPPORTED;	}	for( i=0; i<16; i++ )		// luma coef	{		CQuasar__WriteReg(pIDecoder, HwLumaAddr + i,			MAKEWORD(pLumaData[2*i], pLumaData[2*i+1]));	}	for( i=0; i<16; i++ )		// chroma coef	{		CQuasar__WriteReg(pIDecoder, HwLumaAddr + i + 32,			MAKEWORD(pChromaData[2*i], pChromaData[2*i+1]));	}	CQuasar__WriteDM(pIDecoder, pQ4->DICOM_Control.addr, Ctrl1);	IDecoder_WriteDM(pIDecoder, pQ4->DICOM_UpdateFlag.addr, 1);	return Q_OK;}QRESULT CEM847X__SetDisplayFilterCoef(IDecoder* pIDecoder, BYTE* pCoef, DWORD dwSizeIn){	CQuasar *this = (CQuasar*) pIDecoder;	if( (pCoef == NULL) || (dwSizeIn < 6*32) )		return Q_FAIL;	OSmemcpy(this->Horizontal4tapLumaCoef, pCoef, 32);	OSmemcpy(this->Horizontal4tapChromaCoef, pCoef, 32);	OSmemcpy(this->Vertical2tapLumaCoef, pCoef, 32);	OSmemcpy(this->Vertical2tapChromaCoef, pCoef, 32);	OSmemcpy(this->Vertical4tapLumaCoef, pCoef, 32);	OSmemcpy(this->Vertical4tapChromaCoef, pCoef, 32);	CEM847X__SetDisplayFilter(pIDecoder, this->HorizontalFilter, NULL, 0);	return CEM847X__SetDisplayFilter(pIDecoder, this->VerticalFilter, NULL, 0);}ULONG EM847xFindBestPllSet(ULONG F0, BYTE* pn, BYTE* pm){	int ppmError = 10;	// 50ppm = 0.005%; 100ppm=0.01%; 1000ppm=0.1%	int InputFreq = 27000000;	// Hz	int PPM = 1000000;			// ppm per unit	int n,m;	BYTE Noptim=255, Moptim=127;	int LowLimit = 10000000, UpperLimit = 100000000;	int F, Foptim;	int minDiff = F0*100;	if( minDiff < 0 )		minDiff = 0x7fffffff;	// default value. Must be overwritten	Foptim = 0;	for( m=1; m<64; m++)	{		for( n=1; n<256; n++)		{			F = 10 * ( (InputFreq / 10) * (n+2) / (m+2) );			if( (F > LowLimit) && (F < UpperLimit) )			{				if( ((int)(F - F0)) > (-minDiff) &&					((int)(F - F0)) < (minDiff) )				{					minDiff = F - F0;					if(minDiff<0)						minDiff = -minDiff;					Foptim = F;					Noptim = (BYTE)n;					Moptim = (BYTE)m;				}				if( ((int)((F - F0)*100) > (int)(-ppmError * F0 * 100 / PPM)) &&					((int)((F - F0)*100) < (int)(ppmError * F0 * 100 / PPM) ))				{					goto end;				}			}		}	}end:	if( m<64 && n<256 )	{		*pn = (BYTE)n;		*pm = (BYTE)m;		return F;	}	else	{		*pn = Noptim;		*pm = Moptim;		return Foptim;	}}QRESULT CEM847X__ProgramVClk(IDecoder* pIDecoder, DWORD* pFreq){	//	CQuasar *this = (CQuasar*) pIDecoder;	DWORD N=0, M=0, F;	// Internal PLL has Fout = FRef*(N+2)/(M+2), where N = bits 7..0, M = bits 13..8	switch(*pFreq)	{	case 0:		IDecoder_WriteReg(pIDecoder, VID_INTERNAL_PLL,			USE_EXTVCLK_FOR_VCLK );// no Q4_POWER_UP_VIDEO_PLL		break;	case 27000000:		IDecoder_WriteReg(pIDecoder, VID_INTERNAL_PLL,			USE_VIDEO_PLL_FOR_VCLK | Q4_POWER_UP_VIDEO_PLL | (3<<8) | 3 );		break;	default:		F = EM847xFindBestPllSet(*pFreq, (BYTE*)&N, (BYTE*)&M);		QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   F0=%d F=%d M=%d N=%d"),			*pFreq, F, M, N ));		IDecoder_WriteReg(pIDecoder, VID_INTERNAL_PLL,			USE_VIDEO_PLL_FOR_VCLK  | Q4_POWER_UP_VIDEO_PLL | (M<<8) | N );		// PixelFreq will be smaller than the wanted one because of arithmetic aproximation		// We have to reevaluate:		*pFreq = OSDDiv(27000000, N+2, M+2);		break;	}	return Q_OK;}/****f* HwLib/IDecoder_SetAudioSampleRate * USAGE *	QRESULT IDecoder_SetAudioSampleRate(IDecoder* pIDecoder, DWORD Rate) *	QRESULT CEM840X__SetAudioSampleRate(IDecoder* pIDecoder, DWORD Rate) *	QRESULT CEM847X__SetAudioSampleRate(IDecoder* pIDecoder, DWORD Rate) *	QRESULT CEM848X__SetAudioSampleRate(IDecoder* pIDecoder, DWORD Rate) * DESCRIPTION *	IDecoder_SetAudioSampleRate sets the audio sample rate to 32kHz, 44.1kHz or default 48kHz *	It is called only by IDecoderBoard_AudioSetSampleRate. * PARAMETERS *	IN IDecoder* pIDecoder - pointer to the decoder object *	IN DWORD Rate - any of 32000, 44100 or 48000/********************************************************************************************/QRESULT CEM847X__SetAudioSampleRate(IDecoder* pIDecoder, DWORD Rate){	CQuasar *this = (CQuasar*) pIDecoder;	Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ;	DWORD Value;	this->CurrentAudioRate = Rate;	QDbgLog((QLOG_TRACE, QDebugLevelTrace, TEXT("   CEM847X__SetAudioSampleRate=%lu"), Rate));	// 24 bits = 0xc0, EIAJ/I2S mask 0x10, invert mask 0x08, right justified mask 0x04	CQuasar__WriteDM(pIDecoder, pQ4->Jda1_config.addr,		(this->AudioDacBitsPerSample == 16) ? 0x84 : 0xC0);	// Config15:8, Config7:0 from JDA1 spec - default recommended 0x0001 = PMW1, CompensatorIN, DitherON	CQuasar__WriteDM(pIDecoder, pQ4->Jda1_setup_lo.addr, 0x0006);	// Config31:24, Config23:16 from JDA1 spec - default recommended 0x0000	// = 44.1kHz,pseudo-slave, disable mute on softmute, slow softmute	switch(Rate)	{	case 44056:		Value = 0x0108 | 0x0060;		break;	case 52734:		Value = 0x0108 | 0x00e0;		break;	case 16000:		Value = 0x8108 | 0x0040;		break;	case 32000:		Value = 0x0108 | 0x0040;		break;	case 22050:		Value = 0x8108 | 0x0000;		break;	case 44100:		Value = 0x0108 | 0x0000;		break;	case 88200:	// Untested - Need 88.2Khz PCM file		Value = 0x0108 | 0x0000;	// jda1 clock is programmed at 44100		break;	case 24000:		Value = 0x8108 | 0x0020;		break;	case 96000:		Value = 0x0108 | 0x0020;	// jda1 clock is programmed at 48000		break;	default:	case 48000:		Value = 0x0108 | 0x0020;		break;	}//ccc force the microcode to update the new settings	CQuasar__WriteDM(pIDecoder, pQ4->Jda1_setup_hi.addr, Value);	CQuasar__WriteReg(pIDecoder, AUDIO_jda1_setup_hi, Value);	if( this->AudioSampleRateSupport_96kHz )	{		this->ChannelStatus = (this->ChannelStatus & ~Q3_ASpdifStat1_rate) |			((Rate==32000) ? Q3_ASpdifStat1_32k :			((Rate==44100) ? Q3_ASpdifStat1_44k :			((Rate==88200) ? Q3_ASpdifStat1_88k :			((Rate==96000) ? Q3_ASpdifStat1_96k :			Q3_ASpdifStat1_48k))));	}	else	{		this->ChannelStatus = (this->ChannelStatus & ~Q3_ASpdifStat1_rate) |			(((Rate==32000) || (Rate==64000)) ? Q3_ASpdifStat1_32k :			(((Rate==44100) || (Rate==88200)) ? Q3_ASpdifStat1_44k :			Q3_ASpdifStat1_48k));	}	CQuasar__WriteReg(pIDecoder, AUDIO_spdif_chstat1, HIWORD(this->ChannelStatus));	return Q_OK;}BOOL FindDividerCoef(DWORD numerator, DWORD denominator, DWORD* pn, DWORD* pm){	//            numerator      M	// Problem:  ----------- = ----. Find M and N, M<=0xFFFF, N<=0xFFFF.	//           denominator    M+N	// Find the common factors of numerator and denominator and divide by them	while (1)	{		if ( (numerator<0x10000) && ((denominator - numerator)<0x10000) )			break;		if (((numerator % 2) == 0) && ((denominator % 2) == 0))		{			numerator = numerator / 2;			denominator = denominator / 2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -