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

📄 csm2288.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 3 页
字号:
			OSmemcpy((void*)this->XferUcodeParameters.SysLinAddr, (BYTE*)pUCode+offset, maxxfer);			t0 = OSTimeGetTime();			IDecoder_WriteDataToLBC(this->m_pIDecoder,				HostMaster_W4_LWCH0_Ucode | Sm2288_Interface | LBC_Swap_Bytes,				this->XferUcodeParameters.SysPhysAddr, maxxfer);			while( IDecoder_ReadReg(this->m_pIDecoder, QPM_from_host_xfer_cnt) )			{				OSTimeDelay(1000);				if ( (OSTimeGetTime()-t0) > 10 )				{					QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT("   Csm2288__HwReset XFER_UCODE_BURST_SYS FAILED %d ms"), OSTimeGetTime()-t0));					return Q_FAIL;				}			}			offset+=maxxfer;			if (offset==totalsize)				break;		}		IDecoder_WriteReg(this->m_pIDecoder, 0x1fe5, Mux1);		IDecoder_WriteReg(this->m_pIDecoder, 0x1fe6, Mux2);	}	else	// INFO_SM_XFER_UCODE_BURST_DRAM	{		// intel burst lasts about 90000 microseconds.		DWORD maxxfer,offset=0;		if (this->XferUcodeParameters.DramSizeInBytes == 0)		{			QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   Csm2288__HwReset XFER_UCODE_BURST_DRAM FAILED")));			return Q_FAIL;		}		QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT("   Csm2288__HwReset XFER_UCODE_BURST_DRAM")));				while(1)		{			// use 32k of Dram (0x8000 bytes) at a harcoded address to			// load the StreamMachine microcode first in Dram (slave),			maxxfer = min(totalsize-offset, this->XferUcodeParameters.DramSizeInBytes);			#if 1			IDecoder_WriteDramSlave(this->m_pIDecoder, 				this->XferUcodeParameters.DramAddr, (DWORD *)((BYTE*)pUCode+offset), maxxfer);#else			//test W4 transfer when VideoIn is already started			#define W0						0x1C10			#define W4						0x1CF0			temp = IDecoder_ReadReg(this->m_pIDecoder, DRAM_portmux);			QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   temp= %x"),temp));			if((temp & DRAM_portmux_CHW0_Mask) == DRAM_portmux_W0_to_CHW0)			{				CQuasar__ChannelWriteDramSlave(this->m_pIDecoder, W0,					this->XferUcodeParameters.DramAddr, (DWORD *)((BYTE*)pUCode+offset), maxxfer);			}			else			{				IDecoder_WriteReg(this->m_pIDecoder, 0x1fe5, 1);				IDecoder_WriteReg(this->m_pIDecoder, 0x1fe6, 5);				CQuasar__ChannelWriteDramSlave(this->m_pIDecoder, W4,					this->XferUcodeParameters.DramAddr, (DWORD *)((BYTE*)pUCode+offset), maxxfer);				IDecoder_WriteReg(this->m_pIDecoder, 0x1fe5, 4);				IDecoder_WriteReg(this->m_pIDecoder, 0x1fe6, 5);			}#endif			IDecoder_WriteDataToLBC(this->m_pIDecoder,				Dram_CHR0_LWCH0_Ucode | Sm2288_Interface | LBC_Swap_Bytes,				this->XferUcodeParameters.DramAddr, maxxfer);			OSTimeDelay(2000);// 1500 microseconds has proved to be not enough.						offset+=maxxfer;			if (offset==totalsize)				break;		}	}	 	if(Info & INFO_SM_WAIT_TXFIFO) {		DWORD timeleft=SM2288_RC_TO_TX_DELAY_MS;		int i=0;				// read four answers within timeout		// according to Scott Henry dec 18th 2002		while (1) {			DWORD temp=IMpegEncoder_ReadTXFifo(pIMpegEncoder,&timeleft);			if (timeleft==0)  				break;			else {				// sm2288 firmware version is the second message (Emmanuel)				if (i==1) this->CurrentMicrocodeVersion=temp;								QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   Csm2288__HwReset TX_FIFO after download ucode= 0x%04x"),temp));				i++;			}						if (i==4) break;		}	}		if(Info & INFO_SM_PARAMS) {		if( pParams == NULL ) {			// hardware library params.h table does not exist.			QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   Csm2288__HwReset caller did not supply params table")));			// This should be fatal!		}		else			Csm2288__WriteEncodingParams(pIMpegEncoder, pParams, nBytesParams, Info);	}		if(Info & INFO_SM_START)		Csm2288__WriteCommand(pIMpegEncoder, SM2288_START, Info);	return Q_OK;}/****f* HwLib/IMpegEncoder_WriteCommand * USAGE *	BOOL IMpegEncoder_WriteCommand(IMpegEncoder* pIMpegEncoder, DWORD Command, DWORD Info) *	BOOL Csm2288__WriteCommand(IMpegEncoder* pIMpegEncoder, DWORD Command, DWORD Info) * DESCRIPTION *	IMpegEncoder_WriteCommand - send encoding parameters to Mpeg encoder hardware * PARAMETERS *	IN IMpegEncoder* pIMpegEncoder - pointer to the MpegEncoder object *	IN DWORD Command - one of specific MpegEncoder commands. *	For SM2288 one of SM2288_STOP, SM2288_START, SM2288_PAUSE, SM2288_RESUME. *	IN DWORD Info - use INFO_SM_WAIT_TXFIFO_CMD to wait for acknowledges after writing the parameters./********************************************************************************************/BOOL Csm2288__WriteCommand(IMpegEncoder* pIMpegEncoder, DWORD Command, DWORD Info){	QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   Csm2288__WriteCommand queueing 0x%04x in RC_FIFO"), Command));	Csm2288__Write(pIMpegEncoder, SM2288_RC_FIFO, Command);	if(Info & INFO_SM_WAIT_TXFIFO_CMD) {		DWORD timeleft=SM2288_RC_TO_TX_DELAY_MS;				DWORD temp=IMpegEncoder_ReadTXFifo(pIMpegEncoder,&timeleft);		if (timeleft>0)			QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   Csm2288__WriteCommand TX_FIFO 0x%04x"), temp));	}	return TRUE;}/****f* HwLib/IMpegEncoder_WriteEncodingParams * USAGE *	BOOL IMpegEncoder_WriteEncodingParams(IMpegEncoder* pIMpegEncoder, void* pData, DWORD nBytes, DWORD Info) *	BOOL Csm2288__WriteEncodingParams(IMpegEncoder* pIMpegEncoder, void* pData, DWORD nBytes, DWORD Info) * DESCRIPTION *	IMpegEncoder_WriteEncodingParams - send encoding parameters to Mpeg encoder hardware * PARAMETERS *	IN IMpegEncoder* pIMpegEncoder - pointer to the MpegEncoder object *	IN void* pData - pointer to the table containing the encoding parameters. The format of data is * specific to the Mpeg encoder hardware. * For SM2288 every parameter is described in a WORD, the HIBYTE is the index and LOBYTE is * the corresponding data. In order to update the parameters written the list should finish with 0xb801. *	IN DWORD nBytes - size of the data in bytes *	IN DWORD Info - use INFO_SM_WAIT_TXFIFO_PARAMS to wait for acknowledges after writting the parameters./********************************************************************************************/BOOL Csm2288__WriteEncodingParams(IMpegEncoder* pIMpegEncoder, void* pData, DWORD nBytes, DWORD Info){	DWORD i;	WORD* pWordParams = (WORD*)pData;		// download default parameters	for(i=0;i<(nBytes/sizeof(WORD));i++)		Csm2288__Write(pIMpegEncoder, SM2288_PARAM_DOWNLOAD, pWordParams[i] );	if(Info & INFO_SM_WAIT_TXFIFO_PARAMS) {		DWORD timeleft=SM2288_RC_TO_TX_DELAY_MS;				DWORD temp=IMpegEncoder_ReadTXFifo(pIMpegEncoder,&timeleft);		if (timeleft>0)			QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("   Csm2288__WriteEncodingParams TX_FIFO after download params= 0x%04x"), temp ));	}		return TRUE;}/****f* HwLib/IMpegEncoder_ReadData * USAGE *	BOOL IMpegEncoder_ReadData(IMpegEncoder* pIMpegEncoder, DWORD Type, DWORD nBytes) *	BOOL Csm2288__ReadData(IMpegEncoder* pIMpegEncoder, DWORD Type, DWORD nBytes) * DESCRIPTION *	IMpegEncoder_ReadData - program the encoder to send data through DMA * PARAMETERS *	IN IMpegEncoder* pIMpegEncoder - pointer to the MpegEncoder object *	IN DWORD Type - audio, video, A/V multiplexed *	IN DWORD nBytes - number of bytes to send - multiple of 8/********************************************************************************************/BOOL Csm2288__ReadData(IMpegEncoder* pIMpegEncoder, DWORD Type, DWORD nBytes){	QDbgLog((QLOG_TRACE,QDebugLevelError,TEXT("Csm2288__ReadData: untested code?")));	return FALSE;			if(nBytes%8)	{		QDbgLog((QLOG_TRACE, QDebugLevelError,			TEXT("   Csm2288__ReadData nBytes=%x NOT MULTIPLE of 8 ???"), nBytes));		return FALSE;	}	Csm2288__Write(pIMpegEncoder, SM2288_DMA_INFO1,		(Type & ~SM2288_INTEL_BURST) | DMA_REQ_POL_HIGH | DMA_READ);	Csm2288__Write(pIMpegEncoder, SM2288_DMA_INFO2, 0);	// Intel burst mode or Intel single access mode - EM847x doesn't output a DMA_ACK	Csm2288__Write(pIMpegEncoder, SM2288_DMA_COUNT, (Type & SM2288_INTEL_BURST) | (nBytes/8));	Csm2288__SetCurrentIrqMask(pIMpegEncoder, DMA_DONE | DMAENABLE);	return TRUE;/*                                                     ____Next waveforms describes the  DMAREQ (active high) and INTR (active low) when executing:IMpegEncoder_HwReset, IDecoderBoard_WriteDataToLBC and IDecoderBoard_ReadDataFromLBC.             <HwReset><    WriteDataToLBC    ><        ReadDataFromLBC           >             ____          ________________                    ________________DMAREQ   XXXX    |________|                |__________________|                |__________         ______________________________       _____________________________INTR     XXXX                              |_____|                             |______            +    +        +                +     +            +                +            |    |        |                |     |            |                |             |    |        |                |     |            |                Finish the DMA transfer            |    |        |                |     |			  program DMA_START in SM2288_DMA_COUNT register            |    |        |                |     clear SM2288_INT_EN_CTRL register            |    |        |                Finish the DMA transfer			|    |        program DMA_START in SM2288_DMA_COUNT register			|    Program DMA_REQ polarity high			Unreset LBC channel = SM reset	*/}/****f* HwLib/IMpegEncoder_WriteData * USAGE *	BOOL IMpegEncoder_WriteData(IMpegEncoder* pIMpegEncoder, DWORD Type, DWORD nBytes) *	BOOL Csm2288__WriteData(IMpegEncoder* pIMpegEncoder, DWORD Type, DWORD nBytes) * DESCRIPTION *	IMpegEncoder_WriteData - program the encoder to send data through DMA * PARAMETERS *	IN IMpegEncoder* pIMpegEncoder - pointer to the MpegEncoder object *	IN DWORD Type - audio, video, A/V multiplexed *	IN DWORD nBytes - number of bytes to send - multiple of 8/********************************************************************************************/BOOL Csm2288__WriteData(IMpegEncoder* pIMpegEncoder, DWORD Type, DWORD nBytes){	QDbgLog((QLOG_TRACE,QDebugLevelError,TEXT("Csm2288__WriteData: untested code?")));	return FALSE;	if(nBytes%8)	{		QDbgLog((QLOG_TRACE, QDebugLevelError,			TEXT("   Csm2288__WriteData nBytes=%x NOT MULTIPLE of 8 ???"), nBytes));		return FALSE;	}	Csm2288__Write(pIMpegEncoder, SM2288_DMA_INFO1,		(Type & ~SM2288_INTEL_BURST) | DMA_REQ_POL_HIGH | DMA_WRITE);	Csm2288__Write(pIMpegEncoder, SM2288_DMA_INFO2, 0);	// Intel burst mode or Intel single access mode - EM847x doesn't output a DMA_ACK	Csm2288__Write(pIMpegEncoder, SM2288_DMA_COUNT,		(Type & SM2288_INTEL_BURST) ? (DMA_START | (nBytes/8)) : (nBytes/8));	Csm2288__SetCurrentIrqMask(pIMpegEncoder, DMA_DONE);	return TRUE;}/****f* HwLib/IMpegEncoder_SetCurrentIrqMask * USAGE *	void IMpegEncoder_SetCurrentIrqMask(IMpegEncoder* pIMpegEncoder, DWORD IrqMask) *	void Csm2288__SetCurrentIrqMask(IMpegEncoder* pIMpegEncoder, DWORD IrqMask) * DESCRIPTION *	IMpegEncoder_SetCurrentIrqMask - sets "CurrentIrqMask" variable and updates the *	interrupt mask in firmware/hardware of SM2288. *	The possible sources of interrupt from SM2288 are: *	I2C_IDLE			0x2000 *	DMAENABLE			0x1000 *	AS_ALE_PROTECT		0x0800 *	DMA_REQ_ACK			0x0200 *	DRAM_FIFO_FULL		0x0080 *	DRAM_FIFO_EMPTY		0x0040 *	RC_FIFO_EMPTY		0x0008 *	TX_FIFO_FULL		0x0004 *	TX_FIFO_NOT_EMPTY	0x0002 *	DMA_DONE			0x0001 * *	It is called to enable/disable hardware interrupts. * PARAMETERS *	IN IMpegEncoder* pIMpegEncoder - pointer to the decoder object *	IN DWORD IrqMask - combination of flags mentioned above * SEE ALSO *  IMpegEncoder_GetCurrentIrqMask/********************************************************************************************/void Csm2288__SetCurrentIrqMask(IMpegEncoder* pIMpegEncoder, DWORD IrqMask){	Csm2288* this = (Csm2288*) pIMpegEncoder;	this->CurrentIrqMask = IrqMask;	Csm2288__Write(pIMpegEncoder, SM2288_INT_EN_CTRL, IrqMask);}/****f* HwLib/IMpegEncoder_GetCurrentIrqMask * USAGE *	DWORD IMpegEncoder_GetCurrentIrqMask(IMpegEncoder* pIMpegEncoder) *	DWORD Csm2288__GetCurrentIrqMask(IMpegEncoder* pIMpegEncoder) * PARAMETERS *	IN IMpegEncoder* pIMpegEncoder - pointer to the decoder object * RETURN VALUE *	returns "CurrentIrqMask" variable previously set by IMpegEncoder_SetCurrentIrqMask * SEE ALSO *  IMpegEncoder_SetCurrentIrqMask/********************************************************************************************/DWORD Csm2288__GetCurrentIrqMask(IMpegEncoder* pIMpegEncoder){	Csm2288* this = (Csm2288*) pIMpegEncoder;	return this->CurrentIrqMask;}

⌨️ 快捷键说明

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