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

📄 ci2c.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
字号:
/******************************************************************************  CI2C.c : Implementation of the I2C interface*  REALmagic Quasar Hardware Library*  Created by Aurelia Popa-Radu*  Copyright Sigma Designs Inc*  Sigma Designs Proprietary and confidential*  Created on 8/27/99*  Description:*****************************************************************************/#include "pch.h"#include "ci2c.h"///////////////////////////////////////////////////////////////////////////// CreateInstancevoid CI2C__CreateInstance(void **pv, DWORD dwInstance){    CI2C__New((CI2C **)pv, TEXT("I2C through Quasar"), TRUE, dwInstance);}// constructionvoid CI2C__New ( CI2C** ppCI2C, TCHAR *pName, BOOL bAllocate, DWORD dwInstance){	CI2C *this = *ppCI2C ;	if (bAllocate)	{		// Allocate CI2C		*ppCI2C = OSmalloc(sizeof(CI2C));		this = (CI2C*) *ppCI2C;		if(this == NULL)			return;		OSmemset(this, 0, sizeof(CI2C));	}	// Call CObject constructor with bAllocate = FALSE	CObject__New ((CObject**)ppCI2C, pName, FALSE, dwInstance);	// Initialize virtual table#if defined EM85XX_OBJECT	// 85xx has I2C implemented in hardware	this->VTableI2C.Delete					= CI2C__Delete;	this->VTableI2C.Init					= CEM85xxI2C__Init;	this->VTableI2C.Write					= CEM85xxI2C__Write;	this->VTableI2C.Read					= CEM85xxI2C__Read;	this->VTableI2C.Write_NoSubAddr			= CEM85xxI2C__Write_NoSubAddr;	this->VTableI2C.Read_NoSubAddr			= CEM85xxI2C__Read_NoSubAddr;	this->VTableI2C.SetI2CAddress			= CI2C__SetI2CAddress;	this->VTableI2C.InitPropertySet			= CI2C__InitPropertySet;#else	// 84xx has I2C implemented with 2 PIOs	this->VTableI2C.Delete					= CI2C__Delete;	this->VTableI2C.Init					= CI2C__Init;	this->VTableI2C.Write					= CI2C__Write;	this->VTableI2C.Read					= CI2C__Read;	this->VTableI2C.Write_NoSubAddr			= CI2C__Write_NoSubAddr;	this->VTableI2C.Read_NoSubAddr			= CI2C__Read_NoSubAddr;	this->VTableI2C.SetI2CAddress			= CI2C__SetI2CAddress;	this->VTableI2C.InitPropertySet			= CI2C__InitPropertySet;#endif	// Initialize members	this->lpVtbl = &this->VTableI2C;	QueryInterface(this->m_dwInstance, IID_ISETI2CPIO, (void**)&(this->pISetI2CpIO));}// destructionvoid CI2C__Delete ( II2C* pII2C, BOOL bDeleteObject ){	CI2C *this = (CI2C*) pII2C ;	if (this == NULL)		return;	// Call CObject Destructor	CObject__Delete ((IObject*)this, FALSE);	if (bDeleteObject)	{		// Delete CI2C		OSfree(pII2C);	}}void CI2C__Init ( II2C* pII2C ){	CI2C *this = (CI2C*) pII2C ;	I2CPARAMS* pI2Cparams;	ISetI2CpIO_GetI2C_params(this->pISetI2CpIO, (void**)&pI2Cparams);	this->m_dwData0 = pI2Cparams->m_dwData0;	this->m_dwData1 = pI2Cparams->m_dwData1;	this->m_dwDataIN = pI2Cparams->m_dwDataIN;	this->m_dwDataOUT = pI2Cparams->m_dwDataOUT;	this->m_dwClock0 = pI2Cparams->m_dwClock0;	this->m_dwClock1 = pI2Cparams->m_dwClock1;	this->m_dwClkIN = pI2Cparams->m_dwClkIN;	this->m_dwClkOUT = pI2Cparams->m_dwClkOUT;}////////////////////////////////////////////////////////////////////////////////////////////// I2C functions to program any I2C device ( TvEncoder, EEPROM )void CI2C__SetI2CAddress( II2C* pII2C, BYTE WriteAddr, BYTE ReadAddr, int bDelay){	CI2C *this = (CI2C*) pII2C ;	this->m_bI2cWriteAddr = WriteAddr;	this->m_bI2cReadAddr = ReadAddr;	this->m_bDelay = bDelay;}void CI2C__I2C( II2C* pII2C, BOOL clock, BOOL data ){	CI2C *this = (CI2C*) pII2C ;	if(clock)		ISetI2CpIO_WrClock(this->pISetI2CpIO, this->m_dwClock1);	else		ISetI2CpIO_WrClock(this->pISetI2CpIO, this->m_dwClock0);	if(this->m_bDelay)		OSTimeDelay(this->m_bDelay);	// The delay is too long but is not system dependent	if(data)		ISetI2CpIO_WrData(this->pISetI2CpIO, this->m_dwData1);	else		ISetI2CpIO_WrData(this->pISetI2CpIO, this->m_dwData0);	if(this->m_bDelay)		OSTimeDelay(this->m_bDelay);	// The delay is too long but is not system dependent}void CI2C__I2CR( II2C* pII2C, BOOL clock)	// used only for read sequence{	CI2C *this = (CI2C*) pII2C ;	if(clock)		ISetI2CpIO_WrClock(this->pISetI2CpIO, this->m_dwClock1);	else		ISetI2CpIO_WrClock(this->pISetI2CpIO, this->m_dwClock0);	if(this->m_bDelay)		OSTimeDelay(this->m_bDelay);	// The delay is too long but is not system dependent}void CI2C__I2CStart( II2C* pII2C ){	CI2C *this = (CI2C*) pII2C ;	ISetI2CpIO_WrClock( this->pISetI2CpIO, this->m_dwClock1 );	ISetI2CpIO_WrData( this->pISetI2CpIO, this->m_dwData1 );	ISetI2CpIO_SetClockDir( this->pISetI2CpIO, this->m_dwClkOUT );	ISetI2CpIO_SetDataDir(this->pISetI2CpIO, this->m_dwDataOUT );	CI2C__I2C( pII2C, 1, 1 );	CI2C__I2C( pII2C, 1, 0 );	CI2C__I2C( pII2C, 0, 0 );}void CI2C__I2CStop( II2C* pII2C ){	CI2C *this = (CI2C*) pII2C ;	CI2C__I2C( pII2C, 0, 0 );	CI2C__I2C( pII2C, 1, 0 );	CI2C__I2C( pII2C, 1, 1 );	ISetI2CpIO_SetClockDir( this->pISetI2CpIO, this->m_dwClkIN );	ISetI2CpIO_SetDataDir( this->pISetI2CpIO, this->m_dwDataIN );}BOOL CI2C__I2CAck( II2C* pII2C ){	CI2C *this = (CI2C*) pII2C ;	DWORD ulTimeOut = 0x1000;	ISetI2CpIO_SetDataDir( this->pISetI2CpIO, this->m_dwDataIN );	CI2C__I2C( pII2C, 1, 0 );	// wait until data becomes 0	while(--ulTimeOut && (ISetI2CpIO_RdData(this->pISetI2CpIO, this->m_dwData0)) );	if(!ulTimeOut)	{		QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("I2CAckTO")));		return FALSE;	}	CI2C__I2C( pII2C, 0, 0 );	return TRUE;}void CI2C__I2CByte( II2C* pII2C, BYTE b ){	CI2C *this = (CI2C*) pII2C ;	int i;	BYTE bit;	ISetI2CpIO_SetDataDir( this->pISetI2CpIO, this->m_dwDataOUT );	for ( i=0; i<8; i++ )	{		bit = (b&0x80)>>7;		CI2C__I2C( pII2C, 0, bit );		CI2C__I2C( pII2C, 1, bit );		CI2C__I2C( pII2C, 0, bit );		b <<= 1;	}	ISetI2CpIO_SetDataDir( this->pISetI2CpIO, this->m_dwDataIN );}BYTE CI2C__I2CRead( II2C* pII2C ){	CI2C *this = (CI2C*) pII2C ;	int i;	DWORD bit;	DWORD ret = 0;		ISetI2CpIO_SetDataDir( this->pISetI2CpIO, this->m_dwDataIN );	for ( i=0;i<8;i++)	{		CI2C__I2CR( pII2C, 1 );		bit = ISetI2CpIO_RdData(this->pISetI2CpIO, this->m_dwData0);		CI2C__I2CR( pII2C, 0 );		ret = (ret<<1) + bit;	}	return (BYTE)ret;}// I2CStart__I2CByte(I2c_WriteAddress)__I2CAck__I2CByte(SubAddress)__I2CAck__{I2CByte(pData[i])__I2CAck}__I2CStopBOOL CI2C__Write( II2C* pII2C, BYTE adr, BYTE* pData, int n ){// "adr" = address of first register to write// "pData" = pointer to "n" consecutive bytes to write	CI2C *this = (CI2C*) pII2C ;	int i, TimeOutError = 0;	CI2C__I2CStart( pII2C);	CI2C__I2CByte( pII2C, this->m_bI2cWriteAddr);	if( !CI2C__I2CAck(pII2C) )		TimeOutError++;	CI2C__I2CByte( pII2C, adr);	if( !CI2C__I2CAck(pII2C) )		TimeOutError++;	for(i=0; i<n;i++)	{		CI2C__I2CByte( pII2C, pData[i]);		if( !CI2C__I2CAck(pII2C) )			TimeOutError++;	}	ISetI2CpIO_SetDataDir( this->pISetI2CpIO, this->m_dwDataOUT );	CI2C__I2CStop( pII2C );	return TimeOutError ? FALSE:TRUE ;}// I2CStart__I2CByte(I2c_WriteAddress)__I2CAck__I2CByte(SubAddress)__I2CStart__I2CByte(I2c_ReadAddress)__I2CAck__I2CByte(SubAddress)__I2CAck__{I2CByte(pData[i])__Nack}__I2CByte(last)__Ack__I2CStopBOOL CI2C__Read( II2C* pII2C, BYTE adr, BYTE* pData, int n ){// "adr" = address of first register to write// "pData" = pointer to "n" consecutive bytes to write	CI2C *this = (CI2C*) pII2C ;	int i, TimeOutError = 0;	if (n < 1) return FALSE;	CI2C__I2CStart( pII2C );	CI2C__I2CByte( pII2C, this->m_bI2cWriteAddr);	if( !CI2C__I2CAck(pII2C) )		TimeOutError++;	CI2C__I2CByte( pII2C, adr);	if( !CI2C__I2CAck(pII2C) )		TimeOutError++;	//delay(1000);// this delay is very important if the pull-up resistor on I2C Data is not equipped	CI2C__I2CStart( pII2C );	CI2C__I2CByte( pII2C, this->m_bI2cReadAddr);	if( !CI2C__I2CAck(pII2C) )		TimeOutError++;	// fix reading consecutive registers sending NACK in between 2 reads	for( i=0; i < n; i++ )	{		pData[i] = CI2C__I2CRead( pII2C );		ISetI2CpIO_SetDataDir( this->pISetI2CpIO, this->m_dwDataOUT );		if(i == (n-1))		{			//Not-Acknowledge from master			CI2C__I2C( pII2C, 0, 1 );			CI2C__I2C( pII2C, 1, 1 );			CI2C__I2C( pII2C, 0, 1 );		}		else		{			//Acknowledge from master			CI2C__I2C( pII2C, 0, 0 );			CI2C__I2C( pII2C, 1, 0 );			CI2C__I2C( pII2C, 0, 0 );		}	}	CI2C__I2CStop( pII2C );	return TimeOutError ? FALSE:TRUE ;}BOOL CI2C__Write_NoSubAddr( II2C* pII2C, BYTE* pData, int n ){// "adr" = address of first register to write// "pData" = pointer to "n" consecutive bytes to write	CI2C *this = (CI2C*) pII2C ;	int i, TimeOutError = 0;	CI2C__I2CStart( pII2C);	CI2C__I2CByte( pII2C, this->m_bI2cWriteAddr);	if( !CI2C__I2CAck(pII2C) )	  {	    QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("(hmwl->ci2c) Failed to transmit %x!\n"), this->m_bI2cWriteAddr));	    TimeOutError++;	  }	for(i=0; i<n;i++)	{		CI2C__I2CByte( pII2C, pData[i]);		if( !CI2C__I2CAck(pII2C) )		  {		    QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("(hmwl->ci2c) Failed to transmit %x!\n"), pData[i]));		    TimeOutError++;		  }	}	ISetI2CpIO_SetDataDir( this->pISetI2CpIO, this->m_dwDataOUT );	CI2C__I2CStop( pII2C );	return TimeOutError ? FALSE:TRUE ;}BOOL CI2C__Read_NoSubAddr( II2C* pII2C, BYTE* pData, int n ){// "adr" = address of first register to write// "pData" = pointer to "n" consecutive bytes to write	CI2C *this = (CI2C*) pII2C ;	int i, TimeOutError = 0;	if (n < 1) return FALSE;	CI2C__I2CStart( pII2C );	CI2C__I2CByte( pII2C, this->m_bI2cWriteAddr);	if( !CI2C__I2CAck(pII2C) )	    TimeOutError++;		//delay(1000);// this delay is very important if the pull-up resistor on I2C Data is not equipped	CI2C__I2CStart( pII2C );	CI2C__I2CByte( pII2C, this->m_bI2cReadAddr);	if( !CI2C__I2CAck(pII2C) )	    TimeOutError++;	  	// fix reading consecutive registers sending NACK in between 2 reads	for( i=0; i < n; i++ )	{		pData[i] = CI2C__I2CRead( pII2C );		ISetI2CpIO_SetDataDir( this->pISetI2CpIO, this->m_dwDataOUT );		if(i == (n-1))		{			//Not-Acknowledge from master			CI2C__I2C( pII2C, 0, 1 );			CI2C__I2C( pII2C, 1, 1 );			CI2C__I2C( pII2C, 0, 1 );		}		else		{			//Acknowledge from master			CI2C__I2C( pII2C, 0, 0 );			CI2C__I2C( pII2C, 1, 0 );			CI2C__I2C( pII2C, 0, 0 );		}	}	CI2C__I2CStop( pII2C );	return TimeOutError ? FALSE:TRUE ;}QRESULT CI2C__SetProperty( II2C* pII2C,	DWORD PropSet, DWORD PropId, DWORD Flags, void* pData, DWORD dwSizeIn, DWORD* pdwSizeOut){	CI2C* this = (CI2C*) pII2C;	switch(PropId)	{	case eI2cInit:		{		I2cInit_type* pI2cInit = (I2cInit_type*)pData;		CHECK_SIZE(I2cInit)		QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("CI2C__SetProperty_eI2cInit: clock=%x data=%x"),			pI2cInit->PIO_clock, pI2cInit->PIO_data));		ISetI2CpIO_SetI2C_params(this->pISetI2CpIO, (BYTE)pI2cInit->PIO_data, (BYTE)pI2cInit->PIO_clock);		CI2C__Init(pII2C);		}		break;	case eI2cAccess:		{		I2cReadWrite_type* pI2cReadWrite = (I2cReadWrite_type*)pData;		if(pdwSizeOut)			*pdwSizeOut = sizeof(I2cReadWrite_type);		if(dwSizeIn <= sizeof(I2cReadWrite_type))	// no place for data to read or write			return E_INVALID_PROPERTY_BUFFER;		if( dwSizeIn < (sizeof(I2cReadWrite_type) + pI2cReadWrite->nBytes) )	// not enough place for data to read or write			return E_INVALID_PROPERTY_BUFFER;		CI2C__SetI2CAddress( pII2C, (BYTE)(pI2cReadWrite->I2c_WriteAddress),			(BYTE)(pI2cReadWrite->I2c_ReadAddress), pI2cReadWrite->I2c_usDelay);		if(pI2cReadWrite->SubAddress == 0xFFFF)	// no subaddress required		{			return (II2C_Write_NoSubAddr(pII2C, (BYTE*)pI2cReadWrite + sizeof(I2cReadWrite_type),				pI2cReadWrite->nBytes)) ? Q_OK:Q_FAIL;		}		else		{			return (II2C_Write(pII2C, (BYTE)pI2cReadWrite->SubAddress,				(BYTE*)pI2cReadWrite + sizeof(I2cReadWrite_type), pI2cReadWrite->nBytes)) ? Q_OK:Q_FAIL;		}		}		break;	default:		return E_NOT_SUPPORTED;	}	return Q_OK;}QRESULT CI2C__GetProperty( II2C* pII2C,	DWORD PropSet, DWORD PropId, DWORD Flags, void* pData, DWORD dwSizeIn, DWORD* pdwSizeOut){	//	CI2C* this = (CI2C*) pII2C;	switch(PropId)	{	case eI2cAccess:		{		I2cReadWrite_type* pI2cReadWrite = (I2cReadWrite_type*)pData;		if(pdwSizeOut)			*pdwSizeOut = sizeof(I2cReadWrite_type);		if( dwSizeIn <= sizeof(I2cReadWrite_type) )	// no place for data to read or write			return E_INVALID_PROPERTY_BUFFER;		if( dwSizeIn < (sizeof(I2cReadWrite_type) + pI2cReadWrite->nBytes) )	// not enough place for data to read or write			return E_INVALID_PROPERTY_BUFFER;		CI2C__SetI2CAddress( pII2C, (BYTE)(pI2cReadWrite->I2c_WriteAddress),			(BYTE)(pI2cReadWrite->I2c_ReadAddress), pI2cReadWrite->I2c_usDelay);		if(pI2cReadWrite->SubAddress == 0xFFFF)	// no subaddress required		{			return (II2C_Read_NoSubAddr(pII2C, (BYTE*)pI2cReadWrite + sizeof(I2cReadWrite_type),				pI2cReadWrite->nBytes)) ? Q_OK:Q_FAIL;		}		else		{			return (II2C_Read(pII2C, (BYTE)pI2cReadWrite->SubAddress,				(BYTE*)pI2cReadWrite + sizeof(I2cReadWrite_type), pI2cReadWrite->nBytes)) ? Q_OK:Q_FAIL;		}		}		break;	default:		return E_NOT_SUPPORTED;	}	return Q_OK;}void CI2C__InitPropertySet(II2C* pII2C, void* pPropSet, DWORD dwSize){	CI2C* this = (CI2C*) pII2C;	if(dwSize != sizeof(PROPERTY_SET_ITEM))		return;	InitPropSet(pII2C, pPropSet, I2C_SET, eI2cMax,\		this->I2CPropertyList, CI2C__SetProperty, CI2C__GetProperty)}

⌨️ 快捷键说明

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