
unit I2C
{
	public link unit SDA {}
	public link unit SCL {}
	
	link bit SDA_DIR = SDA.D0_DIR;
	link bit SDA_IN = SDA.D0_IN;
	link bit SDA_OUT = SDA.D0_OUT;
	
	link bit SCL_DIR = SCL.D0_DIR;
	link bit SCL_OUT = SCL.D0_OUT;
	
	public uint8 byte0;
	public uint8 byte1;
	public uint8 byte2;
	public uint8 byte3;
	public uint8 byte4;
	public uint8 byte5;
	
	//---------------------------------------------------
	//ʼ
	public void Init()
	{
		SDA_DIR = 1;
		SDA_OUT = 1;
		
		SCL_DIR = 1;
		SCL_OUT = 1;
		
		start_iic();
		end_iic();
		
		delay_1us();
	}
	//---------------------------------------------------
	//һ16λַдһֽ
	public void A2_set_uint8( uint8 DeviceAddr, uint16 addr, uint8 data )
	{
		start_iic();
		write_byte( DeviceAddr );
		write_byte( addr.8(uint8) );
		write_byte( addr.0(uint8) );
		write_byte( data );
		end_iic();
	}
	//һ16λַȡһֽ
	public uint8 A2_get_uint8( uint8 DeviceAddr, uint16 addr )
	{
		start_iic();
		write_byte( DeviceAddr );
		write_byte( addr.8(uint8) );
		write_byte( addr.0(uint8) );
		//end_iic();
		start_iic();
		write_byte( DeviceAddr | 0x01 );
		uint8 data = read_byte();
		NoAck();
		end_iic();
		return data;
	}
	//---------------------------------------------------
	//һ8λַдһֽ
	public void A1_set_uint8( uint8 DeviceAddr, uint8 addr, uint8 data )
	{
		start_iic();
		write_byte( DeviceAddr );
		write_byte( addr );
		write_byte( data );
		end_iic();
	}
	//һ8λַȡһֽ
	public uint8 A1_get_uint8( uint8 DeviceAddr, uint8 addr )
	{
		start_iic();
		write_byte( DeviceAddr );
		write_byte( addr );
		//end_iic();
		start_iic();
		write_byte( DeviceAddr | 0x01 );
		uint8 data = read_byte();
		NoAck();
		end_iic();
		return data;
	}
	//һ8λַȡ6ֽ
	public void A1_get_byte2( uint8 DeviceAddr, uint8 addr )
	{
		start_iic();
		write_byte( DeviceAddr );
		write_byte( addr );
		start_iic();
		write_byte( DeviceAddr | 0x01 );
		byte0 = read_byte();
		Ack();
		byte1 = read_byte();
		NoAck();
		end_iic();
	}
	//һ8λַȡ6ֽ
	public void A1_get_byte4( uint8 DeviceAddr, uint8 addr )
	{
		start_iic();
		write_byte( DeviceAddr );
		write_byte( addr );
		start_iic();
		write_byte( DeviceAddr | 0x01 );
		byte0 = read_byte();
		Ack();
		byte1 = read_byte();
		Ack();
		byte2 = read_byte();
		Ack();
		byte3 = read_byte();
		NoAck();
		end_iic();
	}
	//һ8λַȡ6ֽ
	public void A1_get_byte6( uint8 DeviceAddr, uint8 addr )
	{
		start_iic();
		write_byte( DeviceAddr );
		write_byte( addr );
		start_iic();
		write_byte( DeviceAddr | 0x01 );
		byte0 = read_byte();
		Ack();
		byte1 = read_byte();
		Ack();
		byte2 = read_byte();
		Ack();
		byte3 = read_byte();
		Ack();
		byte4 = read_byte();
		Ack();
		byte5 = read_byte();
		NoAck();
		end_iic();
	}
	//=================================================================================
	//ʼIICͨ
	public void start_iic()
	{
		SDA_OUT = 1;
		SCL_OUT = 1;
		delay_1us();
		SDA_OUT = 0;
		delay_1us();
		SCL_OUT = 0;
		delay_1us();
	}
	//IICͨ
	public void end_iic()
	{
		SDA_OUT = 0;
		SCL_OUT = 1;
		delay_1us();
		SDA_OUT = 1;
		delay_1us();
		SCL_OUT = 1;
		delay_1us();
	}
	//ȴӦź
	public void wait()
	{
		SDA_DIR = 0;
		SDA_OUT = 1;
		delay_1us();
		SCL_OUT = 1;
		delay_1us();
		while( SDA_IN == 1 ) {}
		SCL_OUT = 0;
		delay_1us();
		SDA_DIR = 1;
	}
	//дһֽ
	public void write_byte( uint8 data )
	{
		loop( 8 ) {
			SDA_OUT = data.7(bit);
			data << 1;
			delay_1us();
			SCL_OUT = 1;
			delay_1us();
			SCL_OUT = 0;
			delay_1us();
		}
		wait();
	}
	//һֽ
	public uint8 read_byte()
	{
		uint8 data;
		SDA_DIR = 0;
		SDA_OUT = 1;
		loop( 8 ) {
			data << 1;
			data.0(bit) = SDA_IN;
			SCL_OUT = 1;
			delay_1us();
			SCL_OUT = 0;
			delay_1us();
		}
		SDA_DIR = 1;
		return data;
	}
	//Ӧ
	public void Ack()
	{
		SDA_OUT = 0;		//Ӧ
		delay_1us();
		SCL_OUT = 1;
		delay_1us();
		SCL_OUT = 0;
		delay_1us();
	}
	//ͷӦ
	public void NoAck()
	{
		SDA_OUT = 1;		//Ӧ
		delay_1us();
		SCL_OUT = 1;
		delay_1us();
		SCL_OUT = 0;
		delay_1us();
	}
	//ʱ1΢
	void delay_1us()
	{
		loop( 2 ) {}
	}
}


