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

📄 cem847x.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		else			break;	} 	while (1)	{		if ( (numerator<0x10000) && ((denominator - numerator)<0x10000) )			break;		if (((numerator % 3) == 0) && ((denominator % 3) == 0))		{			numerator = numerator / 3;			denominator = denominator / 3;		}		else			break;	}	while (1)	{		if ( (numerator<0x10000) && ((denominator - numerator)<0x10000) )			break;		if (((numerator % 5) == 0) && ((denominator % 5) == 0))		{			numerator = numerator / 5;			denominator = denominator / 5;		}		else			break;	}	// Divide by 7 as well? What about 13, 17, 19, 23 ...		if( (numerator<0x10000) && ((denominator - numerator)<0x10000) )	{		// multiply back to 3,2 to make sure I get the greatest m, n possible,		// to decrease the ppm variation for VCXO		while (1)		{			if( ((numerator*3)<0x10000) && (((denominator - numerator)*3)<0x10000) )			{				numerator = numerator * 3;				denominator = denominator * 3;			}			else				break;		}		while (1)		{			if( ((numerator*2)<0x10000) && (((denominator - numerator)*2)<0x10000) )			{				numerator = numerator * 2;				denominator = denominator * 2;			}			else				break;		}		*pm = numerator;		*pn = denominator - numerator;		return TRUE;	}	else		return FALSE;}QRESULT CEM848X__SetAudioSampleRate(IDecoder* pIDecoder, DWORD Rate){	CQuasar *this = (CQuasar*) pIDecoder;	Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ;	DWORD n,m;	this->CurrentAudioRate = Rate;	QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT("   CEM848X__SetAudioSampleRate=%lu"), Rate));	// In 848x ACLK256 is obtained from Fin using next formula:	//   Aclk256 = Fin * m/(2*(m+n)), where Fin can be mclk or Damck,	//    m is Jda1_setup_lo symbol -> 0x1FDD register	//    n is Jda1_setup_hi symbol -> 0x1FDE register	if( this->QuasarVersion == EM85XX_JASPER )	{ 		this->AudioSampleRateSupport_96kHz = 0;		if(Rate > 48000)			Rate /= 2;		//   512*Rate/RISC_Clock = m/(m+n)		if( !FindDividerCoef( 512*Rate, this->RISC_Clock, &n, &m) )			return Q_FAIL;		QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   FindDividerCoef SampleRate=%d m=%d, n=%d"),			OSDDiv(this->RISC_Clock, m, 512*(m+n)), m, n ));	}	else	{		//   512*Rate/MClock = m/(m+n)		if( !FindDividerCoef( 512*Rate, this->DramFreq, &n, &m) )			return Q_FAIL;		QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   FindDividerCoef SampleRate=%d m=%d, n=%d"),			OSDDiv(this->DramFreq, m, 512*(m+n)), m, n ));	}	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));	}	//ccc force the microcode to update the new settings	CQuasar__WriteDM(pIDecoder, pQ4->Jda1_setup_lo.addr, n);	CQuasar__WriteDM(pIDecoder, pQ4->Jda1_setup_hi.addr, m);	CQuasar__WriteReg(pIDecoder, AUDIO_jda1_setup_lo, n);	CQuasar__WriteReg(pIDecoder, AUDIO_jda1_setup_hi, m);	CQuasar__WriteReg(pIDecoder, AUDIO_spdif_chstat1, HIWORD(this->ChannelStatus));	return Q_OK;}/****f* HwLib/IDecoder_WriteLbcReg * USAGE *	QRESULT IDecoder_WriteLbcReg(IDecoder* pIDecoder, DWORD Address, DWORD Data) *	QRESULT CEM847X__WriteLbcReg(IDecoder* pIDecoder, DWORD Address, DWORD Data) * PARAMETERS *	IN IDecoder* pIDecoder - pointer to the Decoder object *	IN DWORD Address - address of the register to write *	IN DWORD Data - data to write/********************************************************************************************/QRESULT CEM847X__WriteLbcReg(IDecoder* pIDecoder, DWORD Address, DWORD Data){	//	CQuasar* this = (CQuasar*) pIDecoder;	DWORD timeout = 25;	while( --timeout && (IDecoder_ReadReg(pIDecoder, LBC_status_reg) & 0x0002) );	if(timeout == 0)	{		QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   WriteLbcReg at %x BUSY"), Address ));		IDecoder_WriteReg(pIDecoder, LBC_status_reg, 0xA0);// clear error enable the timeout		return Q_FAIL;	}	IDecoder_WriteReg(pIDecoder, LBC_write_reg_addr, Address);	IDecoder_WriteReg(pIDecoder, LBC_write_reg_data, Data);	QDbgLog((QLOG_TRACE, QDebugLevelTrace, TEXT("   WriteLbcReg at %x = %x"), Address, Data));	return Q_OK;}/****f* HwLib/IDecoder_ReadLbcReg * USAGE *	QRESULT IDecoder_ReadLbcReg(IDecoder* pIDecoder, DWORD Address, DWORD* pData) *	QRESULT CEM847X__ReadLbcReg(IDecoder* pIDecoder, DWORD Address, DWORD* pData) * PARAMETERS *	IN IDecoder* pIDecoder - pointer to the Decoder object/********************************************************************************************/QRESULT CEM847X__ReadLbcReg(IDecoder* pIDecoder, DWORD Address, DWORD* pData){	//	CQuasar* this = (CQuasar*) pIDecoder;	DWORD timeout = 25;	while( --timeout && (IDecoder_ReadReg(pIDecoder, LBC_status_reg) & 0x0001) );	if(timeout == 0)	{		QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   ReadLbcRegA at %x BUSY"), Address ));		IDecoder_WriteReg(pIDecoder, LBC_status_reg, 0xA0);// clear error enable the timeout		return Q_FAIL;	}	IDecoder_WriteReg(pIDecoder, LBC_read_reg_addr, Address);	timeout = 25;	while( --timeout && (IDecoder_ReadReg(pIDecoder, LBC_status_reg) & 0x0001) );	if(timeout == 0)	{		QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   ReadLbcRegD at %x BUSY"), Address ));		IDecoder_WriteReg(pIDecoder, LBC_status_reg, 0xA0);// clear error enable the timeout		return Q_FAIL;	}	*pData = IDecoder_ReadReg(pIDecoder, LBC_read_reg_data);	QDbgLog((QLOG_TRACE, QDebugLevelTrace, TEXT("   ReadLbcReg at %x = %x"), Address, *pData));	return Q_OK;}/****f* HwLib/CEM847X__ReadDataFromLBC * USAGE *	QRESULT IDecoder_ReadDataFromLBC(IDecoder* pIDecoder, IN DWORD PhysAddr, IN DWORD nBytes) *	QRESULT CQuasar__ReadDataFromLBC(IDecoder* pIDecoder, IN DWORD PhysAddr, IN DWORD nBytes) * DESCRIPTION *	CEM840X__ReadDataFromLBC programs EM847x to receive "nBytes" bytes from LBC *	and to write the data in host memory using PCI bus master. PhysAddr must point to a physical *	contiguous buffer of nBytes, otherwise the system hangs. *	"nBytes" can be any value multiple of 4 between 16 and 0xFFFF. * PARAMETERS *	IN IDecoder* pIDecoder - pointer to the decoder object *	IN DWORD Type -  *    - bits 0,1 describing the interface(LBC_config_LG, LBC_config_LG, LBC_config_Sm2288) *    - bit 2 - LBC_config_swap_bytes *    - bits 5,6,7 describing the delay (LBC_config_delay_0,...LBC_config_delay_4) *    - bits 16..23 describing the path of the transfer (LRCH0_Port1_HostMaster,...Dram_CHR0_LWCH0_Ucode) * *	IN DWORD Addr - physical address of the system buffer to write *	IN DWORD nBytes - number of bytes to transfer * SEE ALSO *	IDecoder_WriteDramSlave/********************************************************************************************/QRESULT CEM847X__ReadDataFromLBC(IDecoder* pIDecoder, IN DWORD Type, IN DWORD Addr, IN DWORD nBytes){	DWORD temp;	if( (nBytes < 0x10) || (nBytes > 0xFFFF) || ( nBytes%4 ))	{		QDbgLog((QLOG_TRACE, QDebugLevelError,			TEXT("CQuasar__ReadDataFromLBC Cannot transfer 0x%x!"), nBytes));		return Q_FAIL;	}	switch(Type & 0x00FF0000){	case LRCH0_Port2_HostMaster:		if( CQuasar__ReadReg(pIDecoder, QPM_to_host_xfer_cnt) )		{			QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("CQuasar__ReadDataFromLBC busy xcnt= 0x%x, clear it !"),				CQuasar__ReadReg(pIDecoder, QPM_to_host_xfer_cnt) ));			CQuasar__WriteReg(pIDecoder, QPM_to_host_xfer_cnt, 0);						// do not make this fatal. Try to go on 			// It has proved to be ok in all cases (Emmanuel)			// return Q_FAIL;		}		// any DRAM_portmux should be OK for this type of transfer		// select Port2 for Master Write to Host		CQuasar__WriteReg(pIDecoder, QPM_to_host_master_ena, Port2_to_MasterWriteToHost);		CQuasar__WriteReg(pIDecoder, QPM_master_xfer_enable, 1);		CQuasar__WriteReg(pIDecoder, QPM_to_host_addr_lo, Addr & 0xFFFF);		CQuasar__WriteReg(pIDecoder, QPM_to_host_addr_hi, Addr >> 16);		CQuasar__WriteReg(pIDecoder, QPM_to_host_xfer_cnt, nBytes);		//  connect LRCH0 to Port2 and ask LRCH0 to receive the data from LBC		temp = CQuasar__ReadReg(pIDecoder, LBC_config) & 0xe200;		CQuasar__WriteReg(pIDecoder, LBC_config, temp | LBC_config_LRCH0_to_Port2 | LOBYTE(Type) );		CQuasar__WriteReg(pIDecoder, LBC_read_fifo0_access, 0x8000);// SM2288_DRAM_DATA		CQuasar__WriteReg(pIDecoder, LBC_read_fifo0_cnt, nBytes);		return Q_OK;			case LRCH0_Port1_HostMaster:		if( CQuasar__ReadReg(pIDecoder, QPM_to_host_xfer_cnt) )		{			QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("CQuasar__ReadDataFromLBC busy xcnt= 0x%x, clear it !"),				CQuasar__ReadReg(pIDecoder, QPM_to_host_xfer_cnt) ));			CQuasar__WriteReg(pIDecoder, QPM_to_host_xfer_cnt, 0);						// do not make this fatal. Try to go on 			// It has proved to be ok in all cases (Emmanuel)			// return Q_FAIL;		}		// any DRAM_portmux should be OK for this type of transfer		// select Port1 for Master Write to Host		CQuasar__WriteReg(pIDecoder, QPM_to_host_master_ena, Port1_to_MasterWriteToHost);		CQuasar__WriteReg(pIDecoder, QPM_to_host_addr_lo, Addr & 0xFFFF);		CQuasar__WriteReg(pIDecoder, QPM_to_host_addr_hi, Addr >> 16);		CQuasar__WriteReg(pIDecoder, QPM_to_host_xfer_cnt, nBytes);		//  connect LRCH0 to Port2 and ask LRCH0 to receive the data from LBC		temp = CQuasar__ReadReg(pIDecoder, LBC_config) & 0xe200;		CQuasar__WriteReg(pIDecoder, LBC_config, temp | LBC_config_LRCH0_to_Port1 | LOBYTE(Type) );				CQuasar__WriteReg(pIDecoder, LBC_read_fifo0_access, 0x8000);// SM2288_DRAM_DATA		CQuasar__WriteReg(pIDecoder, LBC_read_fifo0_cnt, nBytes);		return Q_OK;	default:		break;	}			return Q_FAIL;}/****f* HwLib/CQuasar__WriteDataToLBC * USAGE *	QRESULT IDecoder_WriteDataToLBC(IDecoder* pIDecoder, IN DWORD PhysAddr, IN DWORD nBytes) *	QRESULT CQuasar__WriteDataToLBC(IDecoder* pIDecoder, IN DWORD PhysAddr, IN DWORD nBytes) * DESCRIPTION *	CQuasar__WriteDataToLBC programs EM847x to receive "nBytes" bytes from LBC *	and to write the data in host memory using PCI bus master. PhysAddr must point to a physical *	contiguous buffer of nBytes, otherwise the system hangs. *	"nBytes" can be any value multiple of 4 between 16 and 0xFFFF. * PARAMETERS *	IN IDecoder* pIDecoder - pointer to the decoder object *	IN DWORD Type -  *	IN DWORD Addr - physical address of the system buffer to write *	IN DWORD nBytes - number of bytes to transfer * SEE ALSO *	IDecoder_WriteDramSlave/********************************************************************************************/QRESULT CEM847X__WriteDataToLBC(IDecoder* pIDecoder, IN DWORD Type, IN DWORD Addr, IN DWORD nBytes){	DWORD temp;	if( (nBytes < 0x8) || (nBytes > 0xFFFF) || ( nBytes%4 ))	{		QDbgLog((QLOG_TRACE, QDebugLevelError,			TEXT("CQuasar__WriteDataToLBC Cannot transfer 0x%x!"), nBytes));		return Q_FAIL;	}	if ( ((Type & 0x00FF0000) == HostMaster_W4_LWCH0_Dram)	   ||((Type & 0x00FF0000) == HostMaster_W4_LWCH0_Ucode) )	{		if( CQuasar__ReadReg(pIDecoder, QPM_from_host_xfer_cnt) )		{			QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("CQuasar__WriteDataToLBC busy = 0x%x !"),				CQuasar__ReadReg(pIDecoder, QPM_from_host_xfer_cnt) ));			return Q_FAIL;		}		// connect PCI master to W4 and PCI slave to W0 OK for VideoIn		CQuasar__WriteReg(pIDecoder, 0x1fe5, 4);		CQuasar__WriteReg(pIDecoder, 0x1fe6, 5);		// connect W4 to LWCH0		temp = CQuasar__ReadReg(pIDecoder, LBC_config) & 0xfc00;		CQuasar__WriteReg(pIDecoder, LBC_config, temp | LBC_config_LWCH0_to_W4 | LOBYTE(Type) );		// ask LWCH0 to send data to stream machine		if ((Type & 0x00FF0000) == HostMaster_W4_LWCH0_Ucode)			CQuasar__WriteReg(pIDecoder, LBC_write_fifo0_access, 0x001c);// SM2288_UCODE_DOWNLOAD		else			CQuasar__WriteReg(pIDecoder, LBC_write_fifo0_access, 0x8000);// SM2288_DRAM_DATA		CQuasar__WriteReg(pIDecoder, LBC_write_fifo0_cnt, nBytes);		// Set up PCI master to read from system memory		CQuasar__WriteReg(pIDecoder, QPM_from_host_addr_lo, Addr & 0xFFFF);		CQuasar__WriteReg(pIDecoder, QPM_from_host_addr_hi, Addr >> 16);		CQuasar__WriteReg(pIDecoder, QPM_from_host_xfer_cnt, nBytes);		CQuasar__WriteReg(pIDecoder, QPM_xfer_reverse, 0);		CQuasar__WriteReg(pIDecoder, QPM_master_xfer_enable, 1);		return Q_OK;	}	else if( ((Type & 0x00FF0000) == Dram_CHR0_LWCH0_Dram)		||((Type & 0x00FF0000) == Dram_CHR0_LWCH0_Ucode) )	{		if( CQuasar__ReadReg(pIDecoder, DRAM_zcnt(RD0)) )		{			QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("CQuasar__WriteDataToLBC busy = 0x%x !"),				CQuasar__ReadReg(pIDecoder, DRAM_xcnt(RD0)) ));			return Q_FAIL;		}		IDecoder_WriteReg(pIDecoder, DRAM_portmux,			(IDecoder_ReadReg(pIDecoder, DRAM_portmux) & ~DRAM_portmux_CHR0_Mask) |			DRAM_portmux_CHR0_to_LWCH0);		// connect R0a to LWCH0		temp = CQuasar__ReadReg(pIDecoder, LBC_config) & 0xfc00;		CQuasar__WriteReg(pIDecoder, LBC_config, temp | LBC_config_LWCH0_to_R0a | LOBYTE(Type) );		// ask LWCH0 to send data to stream machine		if ((Type & 0x00FF0000) == Dram_CHR0_LWCH0_Ucode)			CQuasar__WriteReg(pIDecoder, LBC_write_fifo0_access, 0x1c);// SM2288_UCODE_DOWNLOAD		else			CQuasar__WriteReg(pIDecoder, LBC_write_fifo0_access, 0x8000);// SM2288_DRAM_DATA		CQuasar__WriteReg(pIDecoder, LBC_write_fifo0_cnt, nBytes);		ProgramDramChannel(RD0, Addr, nBytes)

⌨️ 快捷键说明

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