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

📄 emi2c.c

📁 sigma_designs的tuner驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * emi2c.c *  * $Log: emi2c.c,v $ * Revision 1.2  2006/01/22 00:32:25  bertrand * Ported contents of set_tron from dcc_2_branch to HEAD * * Revision 1.1.1.1.2.4  2006/01/04 19:50:05  tvh * Enable Tunerapps compilation for SMP8634 * * Revision 1.1.1.1.2.3  2005/06/23 11:23:14  michon * fixbuild * * Revision 1.1.1.1.2.1  2005/03/15 06:23:54  bertrand * Added missing standard header * * Revision 1.1.1.1  2005/03/10 00:06:00  bertrand * Initial import of the DTV specific code into the ndc repository * * Revision 1.2  2004/11/30 05:49:17  jpong * tunerapi addition : added property for low and high frequency of the tuner * tunerapp : shows exapmple of this addition * all: debug logging types fixed in DPRINT, _DEBUG = DEBUG * tuv1236d message fix * * Revision 1.1.1.1  2004/11/10 03:02:41  jpong * i2c devices * * Revision 1.8  2004/07/24 00:09:04  jpong * emi2c_read_subaddress and I2CRead now nacks last byte by default. i2c spec. * new flag EMI2C_RD_SUB_NONACKLASTBYTE added. * * Revision 1.7  2004/06/07 23:05:59  jpong * emi2c - bytecount on emi2c_read_subaddress was being updated incorrectly * README has new commandline parameters * * Revision 1.6  2004/05/13 00:36:21  jpong * added RM i2c_hal like API, can be used to replace i2c_hal.o * * Revision 1.5  2004/04/22 01:10:45  jpong * SR flag fix, more rmtypes.. * * Revision 1.4  2004/04/12 19:04:48  jpong * uses RMtypes.. * * Revision 1.3  2004/03/18 23:26:24  jpong * EMI2C_FLAG_NOSR removed, all calls are now NOSR * * Revision 1.2  2004/03/11 06:07:20  jpong * high level functions emi2c_read/write_subaddress, emi2c_send_table added * no stop on start added with EMI2C_FLAG_NOSR * * Revision 1.1.1.1  2004/03/03 03:28:26  jpong * board test * * *//* standard includes *///#include <sys/io.h>#include <stdio.h>#include <string.h>//#include "../include/em_types.h"//#include "../include/dmesg.h"/* mum includes */#define ALLOW_OS_CODE 1#include "rmdef/rmdef.h"#include "llad/include/gbus.h"#include "emhwlib_hal/include/emhwlib_registers.h"//#define GPIO_DIR_ADDR (REG_BASE_system_block + SYS_gpio_dir)//#define GPIO_DATA_ADDR (REG_BASE_system_block + SYS_gpio_data)#include "emhwlib_hal/i2c/include/i2c_hal.h"#include "../helper/helper.h"#include "emi2c.h"/* local defines */#define SCLHI_TIMEOUT 25/* em860x GPIO definition */#define OUT 1#define IN 0/*--------------Utility Functions -----------------*/static RMvoid em_udelay(EMI2C_CONFIG *pC, RMuint32 us){	RMuint32 t0, t1, d;	RMuint32 TotalDelay = us + pC->AdditionalDelay;		assert(pC);	assert(pC->RegBase == REG_BASE_system_block);        // implementation safe for delays smaller than 0xFFFFFFFF/27us = 159 sec        // if SYS_xtal_in_cnt doesn't work - hang here !!	t0 = gbus_read_uint32( pC->pGBus, pC->RegBase + SYS_xtal_in_cnt);        do {                t1 = gbus_read_uint32( pC->pGBus, pC->RegBase + SYS_xtal_in_cnt);                if (t1 >= t0) d = t1 - t0;                else d = 0xFFFFFFFF - t0 + t1 + 1;        } while ( d < (27 * TotalDelay) );}/*---------------Hardware Control------------------*//* Clock Control */static RMvoid em_sclio(EMI2C_CONFIG *pC, RMuint8 out){	assert(pC);	if(out)		gbus_write_uint32(pC->pGBus, pC->RegBase + SYS_gpio_dir, 0x00010001 << pC->PIO_Clock);	else		gbus_write_uint32(pC->pGBus, pC->RegBase + SYS_gpio_dir, 0x00010000 << pC->PIO_Clock);}static RMvoid em_sclset(EMI2C_CONFIG *pC, RMuint8 high){	assert(pC);        if(high)		gbus_write_uint32(pC->pGBus, pC->RegBase + SYS_gpio_data, 0x00010001 << pC->PIO_Clock);	else		gbus_write_uint32(pC->pGBus, pC->RegBase + SYS_gpio_data, 0x00010000 << pC->PIO_Clock); }static RMvoid em_sclget(EMI2C_CONFIG *pC, RMuint8 *pData){	assert(pC);	assert(pData);		*pData = (gbus_read_uint32(pC->pGBus, pC->RegBase + SYS_gpio_data) & (1 << pC->PIO_Clock))?1:0;}/* a device can hold the scl time for a wait state *//* an i2c bus is supposed to have external pullups */static RMstatus em_scltryhi(EMI2C_CONFIG *pC){	RMuint32 count = 0;	RMuint8 data = 0;	RMuint32 timeout = DEFAULT_SCL_HI_TIMEOUT;		assert(pC);		if( pC->SclHiTimeout != 0 )		timeout = pC->SclHiTimeout;	        em_sclset(pC, 1); 	/* if it is in, we are floating hi/we have control				 * and if it is out, set it to 1 */	em_sclio(pC, OUT);		em_sclio(pC, IN); /* float hi using external pullups */	em_sclget(pC, &data);	while (data == 0)	{		if(count++ > timeout)			return -1;		/*sclset(1);*//* OUT is already 1*/		em_sclio(pC, OUT);				em_udelay(pC, 1);		em_sclio(pC, IN);				em_sclget(pC, &data);	}		/* sclset(1);*//* OUT is already 1*/	em_sclio(pC, OUT);		return RM_OK;}/* Data Control */static RMvoid em_sdaio(EMI2C_CONFIG *pC, RMuint8 out){	assert(pC);	if(out)		gbus_write_uint32(pC->pGBus, pC->RegBase + SYS_gpio_dir, 0x00010001 << pC->PIO_Data);	else		gbus_write_uint32(pC->pGBus, pC->RegBase + SYS_gpio_dir, 0x00010000 << pC->PIO_Data);}static RMvoid em_sdaset(EMI2C_CONFIG *pC, RMuint8 high){	assert(pC);	if(high)		gbus_write_uint32(pC->pGBus, pC->RegBase + SYS_gpio_data, 0x00010001 << pC->PIO_Data);	else		gbus_write_uint32(pC->pGBus, pC->RegBase + SYS_gpio_data, 0x00010000 << pC->PIO_Data);}static RMvoid em_sdaget(EMI2C_CONFIG *pC, RMuint8 *pData){	assert(pC);	assert(pData);		*pData = (gbus_read_uint32(pC->pGBus, pC->RegBase + SYS_gpio_data) & (1 << pC->PIO_Data))?1:0;}/*-----------------I2C Calls----------------------*//* in between start and stop, we tristate * in between read/write/ack, we OUT D =0, C =0 */ RMstatus emi2c_start(EMI2C_CONFIG *pC){	RMuint8 sda;	//RMuint8 scl;		assert(pC);	em_sdaset(pC, 1);	em_sdaio(pC, OUT);	em_sdaget(pC, &sda);	if( sda == 0 )		return -1;	/* sda is being held low */	if( em_scltryhi(pC) != RM_OK ) /* sets scl OUT */		return -1;	/*{		// Stop on Start		em_sdaget(pC, &sda);		em_sclget(pC, &scl);		if( (sda == 0) ||		(scl == 0) )		{			if( emi2c_stop(pC) != RM_OK )				return -1;		}		else		{			em_sdaset(pC, 1);			em_sclset(pC, 1);		}		em_sdaio(pC, OUT);		em_sclio(pC, OUT);	}*/	/* now we are at 1,1 for OUT either from stop or manually */		/* Then Start */	em_sdaset(pC, 0);	em_udelay(pC, 4); /*tHD;STA*/	em_sclset(pC, 0);	em_udelay(pC, 5); /*tLOW*/		return RM_OK;}RMstatus emi2c_stop(EMI2C_CONFIG *pC){	assert(pC);	em_sdaset(pC, 0);	em_sdaio(pC, OUT);		if( em_scltryhi(pC) != RM_OK )		return -1;	em_udelay(pC, 4); /*tSU;STO*/	em_sdaset(pC, 1);	em_udelay(pC, 5); /*tBUF*/		/* at this point, both outputs are 1, tristate for easy	 * read or for other devices to grab bus */	em_sdaio(pC, IN);	em_sclio(pC, IN);	return RM_OK;}RMstatus emi2c_sendbyte(EMI2C_CONFIG *pC, RMuint8 uData, RMuint8 *pNack){	RMuint8 uMask=0x80;	RMuint8 i;	RMuint8 b;		assert(pC);	assert(pNack);		em_sclget(pC, &b);	if( b != 0 )		return -1;	/*sclio(OUT);*//*should already be in output mode */ 	em_sdaio(pC, OUT);		for( i = 0; i < 8; i++ )	{		if (uData & uMask)			em_sdaset(pC, 1);		else			em_sdaset(pC, 0);		uMask = uMask >> 1; /* get ready for next bit */				em_udelay(pC, 1); /* tSU;DAT */				/* clock */		if( em_scltryhi(pC) != RM_OK )		{			em_sdaset(pC, 0);			return -1;		}		em_udelay(pC, 4); /* tHIGH */		em_sclset(pC, 0);		em_udelay(pC, 5); /* tHD;DAT */	}	/* Ack/Nack */	em_sdaio(pC, IN);	em_udelay(pC, 1); /* let sda float for slave to drive */	if( em_scltryhi(pC) != RM_OK )	{		em_sdaset(pC, 0);		em_sdaio(pC, OUT);		return -1;	}	em_udelay(pC, 4); /* tHIGH */	em_sdaget(pC, pNack); /* get the ack/Nack */	em_sclset(pC, 0);		em_sdaio(pC, OUT);	em_sdaset(pC, 0); /* hold the bus */		em_udelay(pC, 5); /* tLOW */		return RM_OK;}RMstatus emi2c_readbyte(EMI2C_CONFIG *pC, RMuint8* pData, RMuint32 nackConfiguration){	RMuint8 b = 0;	RMuint8 uData = 0;	RMuint8 i = 0;		assert(pC);	assert(pData);		// make sure we aren't using stray flags	assert( (nackConfiguration & (~(EMI2C_SEND_NACK | EMI2C_SEND_NACK_IF_MISMATCH | EMI2C_SEND_NACK_COMPARE_DATA))) == 0 );		em_sclget(pC, &b); /* see if the slave is holding SCL */	if( b != 0 )		return -1;	b = 0;			em_sdaio(pC, IN);	em_udelay(pC, 1); /* slave now drives */	for ( i = 0; i < 8; i++)	{		if( em_scltryhi(pC) != RM_OK )		{			em_sdaset(pC, 0); /* hold the bus */			em_sdaio(pC, OUT);			return -1;		}		em_udelay(pC, 4); /* tHIGH and tSU;DAT */		uData = uData << 1;		em_sdaget(pC, &b); /* get data while HIGH, spec says data must be stable */		uData |= b;		em_sclset(pC, 0);		em_udelay(pC, 5); /* tHD;DAT not necessary?  doesn't matter*/	}		if( nackConfiguration & EMI2C_SEND_NACK )		em_sdaset(pC, 1); /* sda = 1 for nack */	else	{		if( nackConfiguration & EMI2C_SEND_NACK_IF_MISMATCH )		{			if( uData != (nackConfiguration & EMI2C_SEND_NACK_COMPARE_DATA))				em_sdaset(pC, 1); /* sda = 1 for nack */			else				em_sdaset(pC, 0); /* 0 for ack */		}		else			em_sdaset(pC, 0); /* 0 for ack */	}	em_sdaio(pC, OUT);			em_udelay(pC, 1); /* tSU;DAT */		if( em_scltryhi(pC) != RM_OK )	{		em_sdaset(pC, 0);		return -1;	}	em_udelay(pC, 4); /* tHIGH */	em_sclset(pC, 0);	em_udelay(pC, 5); /* tLOW ,diff from tHD;DAT but same */	*pData = uData;	return RM_OK;}/*-----------------High Level I2C Calls----------------------*/RMstatus emi2c_write_subaddress(EMI2C_CONFIG* pC,				RMuint8 uSlaveAddress,				RMuint8 uSubAddress,

⌨️ 快捷键说明

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