//___________________________________________________________________
//___________________________________________________________________
//  Copyright : 2015 BY HOLTEK SEMICONDUCTOR INC
//  File Name : MasterII.c
// Description: IO模擬IIC主機
//     Note   : ROM SIZE 230 RAM 依據接收發送BUF不同大小不一,最小約15Byte以上
//___________________________________________________________________
//___________________________________________________________________
#include "common.h"
#include "Master_IIC.h"


volatile unsigned char gu8v_IIC_RData[IIC_RXDATALENGHT],gu8v_IIC_WData[IIC_TXDATALENGHT];

/********************************************************************
Drvction: IIC Start
INPUT	:
OUTPUT	:
NOTE	: IIC Start: when CLK is high,SDA change from high to low
********************************************************************/
void Drv_IIC_Start()
{
    IIC_SCL_OUTPUTMODE();
    IIC_SDA_OUTPUTMODE();
    IIC_SDA_OUTPUTHIHG();
    IIC_SCL_OUTPUTHIGH();
	GCC_DELAY(IIC_SPEED);
    IIC_SDA_OUTPUTLOW();
	GCC_DELAY(IIC_SPEED);
    IIC_SCL_OUTPUTLOW();
}
/********************************************************************
Drvction: IIC Stop
INPUT	:
OUTPUT	:
NOTE	:
********************************************************************/
void Drv_IIC_Stop()
{
    IIC_SDA_OUTPUTLOW();
    IIC_SDA_OUTPUTMODE();
	GCC_DELAY(IIC_SPEED);
    IIC_SCL_OUTPUTHIGH();
	GCC_DELAY(IIC_SPEED);
    IIC_SDA_OUTPUTHIHG();
	GCC_DELAY(IIC_SPEED);
    IIC_SDA_INPUTMODE();
}
/********************************************************************
Drvction: IIC 發送ACK繼續接收
INPUT	:
OUTPUT	:
NOTE	:
********************************************************************/
void Drv_IIC_Ack()
{
    IIC_SDA_OUTPUTMODE();
    IIC_SDA_OUTPUTLOW();
    GCC_DELAY(IIC_SPEED);
    IIC_SCL_OUTPUTHIGH();
    GCC_DELAY(IIC_SPEED);
    IIC_SCL_OUTPUTLOW();
    GCC_DELAY(IIC_SPEED);
    IIC_SDA_OUTPUTHIHG();
    GCC_DELAY(IIC_SPEED);
}

//**********************************
//NoAck(1) signal
//**********************************
void Drv_IIC_NoAck(void)
{
	IIC_SDA_OUTPUTMODE();
    IIC_SDA_OUTPUTHIHG();
    GCC_DELAY(IIC_SPEED);
    IIC_SCL_OUTPUTHIGH();
    GCC_DELAY(IIC_SPEED);
    IIC_SCL_OUTPUTLOW();
    GCC_DELAY(IIC_SPEED);
}
/********************************************************************
Drvction: IIC Wait ACK
INPUT	:
OUTPUT	:
NOTE	:
********************************************************************/
void Drv_IIC_WaitACK()
{
    IIC_SDA_INPUTMODE();
    GCC_DELAY(IIC_SPEED);
    IIC_SCL_OUTPUTHIGH();
	unsigned char i=0;
	while(IIC_SDA_ISHIGH() && ( i < 250 ))
	{
	 	i++;
	}
    IIC_SCL_OUTPUTLOW();
   // GCC_DELAY(IIC_SPEED);
}
/********************************************************************
Drvction: IIC Write Byte
INPUT	: WData
OUTPUT	:
NOTE	:
********************************************************************/
void Drv_IIC_WByte(unsigned char WData)
{
    IIC_SDA_OUTPUTMODE();
 	unsigned char i;
 	for( i=0; i<8; i++)
 	{
        IIC_SCL_OUTPUTLOW();
 		GCC_DELAY(IIC_SPEED);
 		if( WData & 0x80 )
 		{
            IIC_SDA_OUTPUTHIHG();
 		}
 		else
 		{
            IIC_SDA_OUTPUTLOW();
 		}
 		GCC_DELAY(IIC_SPEED);
        IIC_SCL_OUTPUTHIGH();
 		GCC_DELAY(IIC_SPEED);
 		WData <<= 1;
 	}
     IIC_SCL_OUTPUTLOW();
     IIC_SDA_INPUTMODE();
}
/********************************************************************
Drvction: IIC Read Byte
INPUT	:
OUTPUT	: RData
NOTE	:
********************************************************************/
unsigned char Drv_IIC_RByte(unsigned char Ack)
{
    IIC_SDA_INPUTMODE();
    IIC_SCL_OUTPUTLOW();
	volatile unsigned char i,RData = 0;
// 	GCC_DELAY(IIC_SPEED);
    IIC_SCL_OUTPUTHIGH();
	for(i=0; i<8; i++)
	{
        IIC_SCL_OUTPUTHIGH()
		GCC_DELAY(IIC_SPEED);
		RData = (RData<<1)|IIC_SDA;
        IIC_SCL_OUTPUTLOW();
		GCC_DELAY(IIC_SPEED);
	}
	if (Ack){
		Drv_IIC_Ack();
	}
	else{
		Drv_IIC_NoAck();
	}
	return RData;
}
/********************************************************************
Drvction: 寫數據到從機
INPUT	:
OUTPUT	:
NOTE	:
********************************************************************/
void Drv_IICWrite_Data(unsigned char Slave_Address,unsigned char WriteLength)
{
	Drv_IIC_Start();
	Drv_IIC_WByte(Slave_Address);
	Drv_IIC_WaitACK();
	Drv_IIC_WByte(gu8v_IIC_WData[0]);
	Drv_IIC_WaitACK();
	unsigned char i;
	for (i = 1; i < WriteLength; i++)
	{
		Drv_IIC_WByte(gu8v_IIC_WData[i]);
		Drv_IIC_WaitACK();
	}
	Drv_IIC_Stop();
}
/********************************************************************
Drvction: 讀取從機數據
INPUT	:
OUTPUT	:
NOTE	:
********************************************************************/
void Drv_IICRead_Data(unsigned char Slave_Address,unsigned char ReadLength)
{
	Drv_IIC_Start();
	Drv_IIC_WByte(Slave_Address+1);
	Drv_IIC_WaitACK();
	gu8v_IIC_RData[0] = Drv_IIC_RByte(1);
	unsigned char i;
	for (i = 1; i < ReadLength-1; i++)
	{
		gu8v_IIC_RData[i] = Drv_IIC_RByte(1);
	}
	gu8v_IIC_RData[ReadLength-1] = Drv_IIC_RByte(0);
	Drv_IIC_Stop();
}