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

📄 i2c.c

📁 Zoran VP2K731 DVD源代码,极具参考价值!
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
						//ACK check
	scl_lo();//ECK clear

//	*PTR(&P7CR_shadow) &= 0xf7;
//	P7CR = *PTR(&P7CR_shadow);		//edt input port
	sda_hi();

	for(i=0;i<4;i++);
	scl_hi();//ECK set
	waittml = 300; 				//300 ms
	while((waittml!=0x00)&&(is_sda_hi()))
		delay_us(1);

	if(waittml==0x00)
	{
		servoflg.e2prom_err = 1;
		bRes = FALSE;
	}

	for(i=0;i<4;i++);
	scl_lo();//ECK clear
	for(i=0;i<4;i++);

//	*PTR(&P7CR_shadow) |= 0x08;
//	P7CR = *PTR(&P7CR_shadow);		
	__EI();

	return bRes;	// Return FALSE if Error, TRUE otherwise
}

void ack_wr(void)
{
	BYTE	count,i;
	BYTE	data;

	data = 0xa0;
//	*PTR(&P7CR_shadow) |= 0x08;
//	P7CR = *PTR(&P7CR_shadow);		

	sda_lo();//EDT clear
	for(i=0;i<4;i++);

	for(count=0;count<8;count++){
		scl_lo();//ECK clear
		for(i=0;i<4;i++);

		if(data&0x80)
			sda_hi();//EDT set	
		else
			sda_lo();//EDT clear

		for(i=0;i<4;i++);
		scl_hi();//ECK set
		for(i=0;i<4;i++);
		data = data<<1;
	}
	
	scl_lo();//ECK clear

//	*PTR(&P7CR_shadow) &= 0xf7;
//	P7CR = *PTR(&P7CR_shadow);		//edt input port
	sda_hi();	// Switch to input mode for SDA

	for(i=0;i<4;i++);
	scl_hi();//ECK set

	while(is_sda_hi())
	{
		for(i=0;i<4;i++);
		scl_lo();	//ECK clear
		for(i=0;i<4;i++);
		scl_hi();	//ECK set
		for(i=0;i<4;i++);

		data = 0xa0;
//		*PTR(&P7CR_shadow) |= 0x08;
//		P7CR = *PTR(&P7CR_shadow);
	
		sda_lo();//EDT clear
		for(i=0;i<4;i++);

		for(count=0;count<8;count++){
			scl_lo();//ECK clear
			for(i=0;i<4;i++);

			if(data&0x80)
				sda_hi();//EDT set	
			else
				sda_lo();//EDT clear

			for(i=0;i<4;i++);
			scl_hi();//ECK set
			for(i=0;i<4;i++);
			data = data<<1;
		}

		scl_lo();//ECK clear

		// *PTR(&P7CR_shadow) &= 0xf7;
		//P7CR = *PTR(&P7CR_shadow);		//edt input port
		sda_hi();	// Switch to SDA input

		for(i=0;i<4;i++);
		scl_hi();//ECK set
	}

	for(i=0;i<4;i++);	
	scl_lo();//ECK clear

	for(i=0;i<4;i++);

//	*PTR(&P7CR_shadow) |= 0x08;
//	P7CR = *PTR(&P7CR_shadow);
}

BYTE EEPROM_ByteRead(BYTE addr){

	BYTE	count,data,i;

	semaphore_set(SEM_EEPROM);	// ZRN SH0215:Avoid conflict between Core and Drive

	__DI();
	
	ack_wr();						//device address set
	if(!is24_wr(addr))
		rtouts("\nER Addr ERROR");	//sub address set

	for(i=0;i<4;i++);
	sda_hi();//EDT set	
	for(i=0;i<4;i++);			//read mode 
	scl_hi();//ECK set
	for(i=0;i<4;i++);
	sda_lo();//EDT clear
	for(i=0;i<4;i++);
	
	if(!is24_wr(0xa1))
		rtouts("\nER Read Mode ERROR");				//
	
//	*PTR(&P7CR_shadow) &= 0xf7;
//	P7CR = *PTR(&P7CR_shadow);		//edt input port
	sda_hi();

	for(count=0;count<8;count++){
		scl_lo();//ECK clear
		for(i=0;i<4;i++);
		if(is_sda_hi())
			data |= 0x01;
		else
			data &= 0xfe;
		if(count<7)
			data = data<<1;
		for(i=0;i<4;i++);
		scl_hi();//ECK set
		for(i=0;i<4;i++);
	}

	scl_lo();//ECK clear
	for(i=0;i<4;i++);
	scl_hi();//ECK set
	for(i=0;i<4;i++);
	scl_lo();//ECK clear

//	*PTR(&P7CR_shadow) |= 0x08;
//	P7CR = *PTR(&P7CR_shadow);	
	
	sda_lo();//EDT clear
	for(i=0;i<4;i++);
	scl_hi();//ECK set
	for(i=0;i<4;i++);
	sda_hi();//EDT set

	__EI();

	semaphore_clear(SEM_EEPROM);	// ZRN SH0215:Avoid conflict between Core and Drive

	return data;
}
#endif // MILLENO
#else//STANDARD_I2C_PROTOCOL
static BOOL wait_sda_lo(void)
{
	int i = I2C_MAX_WAIT/5;
    sda_set_input();
    while(i && !is_sda_lo()) {
		i--;
		delay_us(5);		
	}

	return i?TRUE:FALSE;
}

static BOOL wait_sda_hi(void)
{
	int i = I2C_MAX_WAIT/5;
    sda_set_input();
    while(i && !is_sda_hi()) {
		i--;
		delay_us(5);		
	}
	return i?TRUE:FALSE;
}

static BOOL wait_scl_hi(void)
{
	int i = I2C_MAX_WAIT/5;

    scl_set_input();
    while(i && !is_scl_hi()) {
		i--;
		delay_us(5);		
	}
	return i?TRUE:FALSE;
}

/* i2c_start --------------------------------------------------- i2c_start
|
|  Provides a start bit for the I2C chip on beginning a command.  As with
|  each primal routine in this file, a delay is provided to guarantee that
|  the maximum clocking rate of the I2C is not exceeded.
|
*/
static void i2c_start(void)
{

    scl_hi();
    
    delay_us(HOLDING_TIME*3);
    
    sda_lo();			
    
    delay_us(HOLDING_TIME*3);
    
    scl_lo();
    
    delay_us(HOLDING_TIME*3);

}

/* i2c_stop ----------------------------------------------------- i2c_stop
|
|  Provides a stop bit for the I2C chip on completing a command.  As with
|  each primal routine in this file, a delay is provided to guarantee that
|  the maximum clocking rate of the I2C is not exceeded.
|
*/
static void i2c_stop(void)
{
    sda_lo();
    
    delay_us(HOLDING_TIME*3);
    
    scl_hi();
    
    delay_us(HOLDING_TIME*3);
    
    sda_hi();
    
    delay_us(HOLDING_TIME*3);
    
    scl_lo();
	
    delay_us(HOLDING_TIME*3);

}


/* i2c_clock --------------------------------------------------- i2c_clock
|
|  Issues a clock to the I2C, and returns a sample of the SDA line during
|  the clock high period (this allows the same clock routine to be used for
|  both transmitting and receiving).  The clock is cycled high immediately,
|  assuming that the previous command has provided the appropriate delay.
*/
BOOL i2c_clock( void )
{
	BYTE rel = 1;

    scl_hi();
    
    delay_us(HOLDING_TIME);
    
    if (is_sda_lo()) rel = 0 ;
	
    scl_lo();
    
    delay_us(HOLDING_TIME);
    
	return ( rel ) ;
}

/* i2c_ack ------------------------------------------------- i2c_ack
|
|  Sends an acknowledge to the I2C bus.  Used during continued reads.
*/
void  i2c_ack( void )
{
    sda_lo();
	i2c_clock() ;
    sda_hi();
}


/* i2c_putc ------------------------------------------------- i2c_putc
|
|  transmits eight bits to the I2C, and solicits an ACK after.  If the
|  ACK is received, a TRUE is returned, otherwise FALSE is returned.
*/

static unsigned i2c_putc(unsigned char d)
{


	BYTE i ;

	// send the eight data bits
	for ( i=0 ; i<8 ; i++ ) {
		if ( d & 0x80 ) 
	        sda_hi();
          else
	        sda_lo();
		d  = d  << 1 ;
		i2c_clock() ;
	}

	// solicit ACK.
    sda_hi();	
	return ( !i2c_clock() ) ;

}

/* i2c_getc ----------------------------------------------------- i2c_getc
|
|  receives eight bits from the I2C, returning the set as a byte. Does not
|  issue ACK, since the calling routine may wish to terminate a sequential
|  read operation.  The calling routine is responsible for making sure that
|  SDA is floating (set to 1 in 8051) before calling this routine.
*/

static unsigned char i2c_getc( void )
{

	BYTE i,i2c_data = 0 ;

	for ( i=0 ; i<8 ; i++ ) {
	
		i2c_data *= 2 ;
		
		if ( i2c_clock() ) i2c_data++ ;
		
	}

	return ( i2c_data ) ;

}


static BOOL i2c_select_device( unsigned char addr, unsigned char subaddr )
{

	i2c_start() ;
	if ( i2c_putc( addr ) )
		return ( i2c_putc( subaddr ) ) ;
	else
		return ( FALSE ) ;

}

/*
 * This function writes address, subaddr, and data on the I2C bus. 
 * The bits in the byte are
 * sent in the order of the high bit first and the lowest bit last.
 */

BOOL i2c_write(unsigned char addr, 
				   unsigned char subaddr, 
				   unsigned char dat)
{

	BYTE i ;

    if ( i2c_select_device(addr,subaddr) && i2c_putc( dat ) ) {
        i2c_stop() ;
        usleep(5000); //delay 5 ms
    } else return ( FALSE ) ;

	return ( TRUE ) ;

}

BOOL i2c_write_string( unsigned char addr, unsigned char subaddr, int count, unsigned char *data )
{
	BYTE retry = 10;
	
	while ( count && retry ){
		if ( i2c_write(addr, subaddr, *data) ){
			subaddr++;
			data++;
			count--;
			retry = 10;
		}
		else 
			retry--;
	}
	return ( retry );
}

BOOL i2c_read_string( unsigned char addr, unsigned char subaddr, int count, unsigned char *data )
{
	BYTE i ;

	// set up for reads starting at address 0
	if ( i2c_select_device( addr, subaddr ) ) {
		// send a second start
		i2c_start() ;
		if ( i2c_putc( addr | 1 ) ) {
			for ( i=0 ; i<count ; i++ ) {

				data[i] = ( i2c_getc() ) ;
				if ( i != (count-1) )
					i2c_ack() ;
				else {
					i2c_clock() ;
					i2c_stop() ;
				}
			}
			return ( TRUE ) ;
		}
		else {
			i2c_stop() ;
			return ( FALSE ) ;
		}
	}
	else
		i2c_stop() ;
		return ( FALSE ) ;

}

#endif//STANDARD_I2C_PROTOCOL

⌨️ 快捷键说明

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