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

📄 i2c.c

📁 USB固件驱动,ISP1581评估板的MPEG方案源码
💻 C
字号:
/*
   //*************************************************************************
   //
   //                  P H I L I P S   P R O P R I E T A R Y
   //
   //           COPYRIGHT (c)   1999 BY PHILIPS SINGAPORE.
   //                     --  ALL RIGHTS RESERVED  --
   //
   // File Name:	    I2C.C
   // Author:           Xia Huiyuan
   // Created:          25 Jan.2002
   // Modified:
   // Revision: 		0.0.
   //
   //*************************************************************************
   //
   //*************************************************************************
   */
#include <intrins.h>
#include "standard.h"
#include "Kernel.h"
#include "I2C.h"
//***********************************************************************
//*																		*
//*	                     Global Variable Definition 							*
//*																		*
//***********************************************************************
UC idata I2CDev_UniqueAddr;
UC idata I2C_SubAddr;

I2C_FLAG I2C_Flag;

//***********************************************************************
//*																		*
//*	                 External Variable Definition					 	*
//*																		*
//***********************************************************************
extern UC idata Endpt_FIFO[64];

/*
   //*************************************************************************
   // Main Funcs
   //*************************************************************************
*/
// Since we try to use C++ programming style for this part, 
// a set of bit flags were defined to instead of the function's parameters.   
// This will hepls to reduce the code size. 
 
bit Hal4I2C_Write(UC Length)
{
	UC i;
	UC Data;
		if(I2C_Flag.BITS.WRITESTARTING)
		{
			I2C_SCL =1;
			I2C_SDA =1;

		    Hal4Sys_Wait4US(); 
			//Setup time for a prepeated START condition.	4.7us for standard-mode/600ns for Fast-mode.
			//Since 24Mhz cystal is selected, the cycle for one single word instraction is 500ns.
			//At frist stage, we set the the delay as 4us, late it will be modified to mee the FS spec.
			Hal4I2Csup_StartCond();   //Start

			if(Hal4I2Csup_Send(I2CDev_UniqueAddr))	//Send Sub-adress 7bit+1bit(r/w)
    		    return(I2C_ERROR);
  
			if(Hal4I2Csup_Send(I2C_SubAddr))	//Send Sub-adress 7bit+1bit(r/w)
    		    return(I2C_ERROR);

		}
		if(I2C_Flag.BITS.DATAPHASE)
		{
			for(i=0; i<Length; i++) 
			{	
				Data=Endpt_FIFO[i];
				if ( Hal4I2Csup_Send(Data) ) 
        		return(I2C_ERROR);
		 	}
		}
		if(I2C_Flag.BITS.WRITEENDING)
		{
		    Hal4I2Csup_StopCond();  //Stop condition
			return(I2C_OK);
		}
		return(I2C_OK);
}

bit Hal4I2C_Read(UC Length)
{
UC OrderOfArray;
	if(I2C_Flag.BITS.READSTARTING)
	{
			I2C_SCL =1;
			I2C_SDA =1;

		    Hal4Sys_Wait4US(); 
			//Setup time for a prepeated START condition.	4.7us for standard-mode/600ns for Fast-mode.
			//Since 24Mhz cystal is selected, the cycle for one single word instraction is 500ns.
			//At frist stage, we set the the delay as 4us, late it will be modified to mee the FS spec.
			Hal4I2Csup_StartCond();   //Start

			if(Hal4I2Csup_Send(I2CDev_UniqueAddr))	//Send Sub-adress 7bit+1bit(r/w)
    		    return(I2C_ERROR);
  
			if(Hal4I2Csup_Send(I2C_SubAddr))	//Send Sub-adress 7bit+1bit(r/w)
    		    return(I2C_ERROR);

			//Repeat start (Sr) 
			if(Hal4I2Csup_SCLHigh()) //Set I2C_SCL = 1 and wait HIGH period of the SCL.
		        return(I2C_ERROR) ;

	    Hal4Sys_Wait4US();

		Hal4I2Csup_StartCond(); 
	
   		Hal4I2Csup_Send(I2CDev_UniqueAddr+1); // Read address
	}
	if(I2C_Flag.BITS.DATAPHASE)
	{
		//Bytes transfer from first byte to length-1 byte.
		for (OrderOfArray=0; OrderOfArray < (Length-1); OrderOfArray++)
		{
			if(Hal4I2Csup_Receive(OrderOfArray,0)) return(I2C_ERROR);
		}	
		//These are two cases to receive Last byte. 
		//Case 1: If ACKASSERT=1; transfer will be terminated by Master(non ack).
		//Case 2: If ACKASSERT=0; last byte will be transfered with ACK.
		if(I2C_Flag.BITS.ACKASSERT) 
		{
			//Since the ACK should be asserted by Master 
			//after receiving a last byte data.
			if(Hal4I2Csup_Receive(OrderOfArray,1)) return(I2C_ERROR);
		}
		else
		{
			//Since the ACK should be asserted by SLAVE 
			//after receiving a byte data except last byte.
	
			if(Hal4I2Csup_Receive(OrderOfArray,0)) return(I2C_ERROR);
		}
	}
	if(I2C_Flag.BITS.READENDING)
	{
	  Hal4I2Csup_StopCond();
		return(I2C_OK);
	}	
		return(I2C_OK);
}


/* ------------------------------------------------------------------------- */
/* Supporting functions */
/* ------------------------------------------------------------------------- */

bit Hal4I2Csup_SCLHigh(void)//Set SCL to high and keep at lease 4us or 0.6 us.
{
    int c0;
    
    I2C_SCL = 1;
	for (c0=8*3500; c0!=0; c0--)
	{
		if (I2C_SCL) 
        {
            Hal4Sys_Wait4US(); //High period of the SCL clock, 4.0/0.6us
            return(I2C_OK);
        }
	};
	return(I2C_ERROR);
}

void Hal4I2Csup_StartCond(void)
{
	I2C_SDA = 0 ;//fall time must be less than 300ns.
    Hal4Sys_Wait4US();	
	//Hold time, START condition. 4.0us for ST-mode/0.6 for FS-mode.
    I2C_SCL = 0 ;
    Hal4Sys_Wait4US();//LOW period of the SCL clock.
}

void Hal4I2Csup_StopCond(void)
{
    I2C_SDA = 0;
    Hal4Sys_Wait1US();//Setup-time.   

    I2C_SCL = 1;
    Hal4Sys_Wait4US(); //Setup-time before I2C_SDA rasing. 4.0us st-mode/0.6us fs-mode
    
    I2C_SDA = 1 ;	
    Hal4Sys_Wait4US();//Bus-free time between a STOP and START condition. 4.7us st-mode/1.3 fs-mode.
}

bit Hal4I2Csup_Send(UC SendData)
{
    UC c0;
	UC Data;
    c0 = 0x80; 

	Data = SendData;
	do
	{
		if (Data & c0)  //SendData & 0x80
            I2C_SDA = 1 ;
		else 
            I2C_SDA = 0 ;
        
        Hal4Sys_Wait1US(); //data set-up time, 250ns for ST-mode, 100ns for FS-mode.
        
         c0 >>= 1 ;

		
        if(Hal4I2Csup_SCLHigh()) //Set I2C_SCL = 1 and wait HIGH period of the SCL.
            return(I2C_ERROR) ;
		
        I2C_SCL = 0 ;
        Hal4Sys_Wait4US();//hold-time 5.0us st/0 fs
	
    }while (c0);

    // Check Ack
	I2C_SDA = 1 ; // Gave up SDA and I2C slave device will drives the bit to low.
    Hal4Sys_Wait4US();//Hold time, START condition. 4.0us for ST-mode/0.6 for FS-mode.
    
    if(Hal4I2Csup_SCLHigh()) //Set I2C_SCL = 1 and wait HIGH period of the SCL.
        return(I2C_ERROR);

    if ( I2C_SDA==0 ) //I2C_SDA = 0. Slave device issued an acknowledge. 
	{
        I2C_SCL=0;
        Hal4Sys_Wait4US();//hold-time 5.0us st/0 fs
		return(I2C_OK);
	};
	return(I2C_ERROR);
}

//Master's receiver is requested to issue an ACK=1 to terminated the transfer, 
//This is a signals to slave's transmitter to terminated the transfer. 
bit Hal4I2Csup_Receive(UC count, UC Terminator) 
{
    UC c0;
    UC c1;


    I2C_SDA = 1; // Give up SDA
    Hal4Sys_Wait1US();

	c0 = 0x80;
	c1 = 0;

    do
	{
		if(Hal4I2Csup_SCLHigh()) 
            return(I2C_ERROR);
        
        if (I2C_SDA==1) 
            c1 = c1|c0 ;
		
        I2C_SCL = 0 ;
        Hal4Sys_Wait4US();

        c0 >>= 1;   

	}while(c0);

	if (Terminator)
	  I2C_SDA =1;
	else
	  I2C_SDA =0;
	
    if(Hal4I2Csup_SCLHigh()) 
        return(I2C_ERROR);
    
    Endpt_FIFO[count] = c1;
	I2C_SCL = 0;
	
    return(I2C_OK);
}

void Hal4Sys_Wait4US(void)
{

    // @24MHz
#ifdef WORK_AT_FS_MODE
    _nop_();
#endif
#ifdef WORK_AT_ST_MODE
    _nop_();
    _nop_();
    _nop_(); //time = MACHINECYCLE_AT24MHZ*NumberOfInstruction;
    _nop_();
    _nop_();
    _nop_();
    _nop_(); //time = MACHINECYCLE_AT24MHZ*NumberOfInstruction;
    _nop_();
#endif


}

void Hal4Sys_Wait1US(void)
{

    // @24MHz
    _nop_(); //time = MACHINECYCLE_AT24MHZ*NumberOfInstruction;

}

⌨️ 快捷键说明

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