/**
	************************************************************
	************************************************************
	************************************************************
	*	ļ 	i2c.c
	*
	*	ߣ 		ż
	*
	*	ڣ 		2016-11-23
	*
	*	汾 		V1.0
	*
	*	˵ 		IICIOʼд
	*
	*	޸ļ¼	
	************************************************************
	************************************************************
	************************************************************
**/
//Ƭͷļ
#include "stm32f10x.h"

//Ӳ
#include "i2c.h"
#include "delay.h"
#include "usart.h"


IIC_INFO iic_info;


/*
************************************************************
*	ƣ	IIC_SpeedCtl
*
*	ܣ	IICٶȿ
*
*	ڲ	speedʱ
*
*	ز	
*
*	˵		λ΢
************************************************************
*/
void IIC_SpeedCtl(unsigned short speed)
{

	iic_info.speed = speed;

}

/*
************************************************************
*	ƣ	IIC_Init
*
*	ܣ	IICIOʼ
*
*	ڲ	
*
*	ز	
*
*	˵		ʹÿ©ʽԲлIOڵ
************************************************************
*/
void IIC_Init(void)
{

	GPIO_InitTypeDef gpio_initstruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	gpio_initstruct.GPIO_Mode = GPIO_Mode_Out_OD;			//©ȥл뷽
	gpio_initstruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &gpio_initstruct);
	
	IIC_SpeedCtl(5);
	
	SDA_H;													//SDAߣڿ״̬
	SCL_H;													//SCLߣڿ״̬

}

/*
************************************************************
*	ƣ	IIC_Start
*
*	ܣ	IICʼź
*
*	ڲ	
*
*	ز	
*
*	˵		
************************************************************
*/
void IIC_Start(void)
{
	
	SDA_H;						//SDA
	SCL_H;						//SCL
	DelayUs(iic_info.speed);	//ʱٶȿ
	
	SDA_L;						//SCLΪʱSDAһ½شʼź
	DelayUs(iic_info.speed);	//ʱٶȿ
	SCL_L;						//ǯסSCLߣԱ㷢

}

/*
************************************************************
*	ƣ	IIC_Stop
*
*	ܣ	IICֹͣź
*
*	ڲ	
*
*	ز	
*
*	˵		
************************************************************
*/
void IIC_Stop(void)
{

	SDA_L;						//SDA
	SCL_L;						//SCL
	DelayUs(iic_info.speed);	//ʱٶȿ
	
	SCL_H;						//SCL
	SDA_H;						//SDAߣSCLΪʱSDAһشֹͣź
	DelayUs(iic_info.speed);

}

/*
************************************************************
*	ƣ	IIC_WaitAck
*
*	ܣ	IICȴӦ
*
*	ڲ	timeOutʱʱ
*
*	ز	
*
*	˵		λ΢
************************************************************
*/
_Bool IIC_WaitAck(unsigned int timeOut)
{
	
	
	SDA_H;DelayUs(iic_info.speed);			//SDA
	SCL_H;DelayUs(iic_info.speed);			//SCL
	
	while(SDA_R)							//SDAΪ1ȴӦźӦ0
	{
		if(--timeOut == 0)
		{
			UsartPrintf(USART1, "WaitAck TimeOut\r\n");

			IIC_Stop();						//ʱδյӦֹͣ
			
			return IIC_Err;					//ʧ
		}
		
		DelayUs(iic_info.speed);
	}
	
	SCL_L;									//SCLߣԱշ
	
	return IIC_OK;							//سɹ
	
}

/*
************************************************************
*	ƣ	IIC_Ack
*
*	ܣ	IICһӦ
*
*	ڲ	
*
*	ز	
*
*	˵		SDAΪʱSCLһһӦź
************************************************************
*/
void IIC_Ack(void)
{
	
	SCL_L;						//SCL
	SDA_L;						//SDA
	DelayUs(iic_info.speed);
	SCL_H;						//SCL
	DelayUs(iic_info.speed);
	SCL_L;						//SCL
	
}

/*
************************************************************
*	ƣ	IIC_NAck
*
*	ܣ	IICһǸӦ
*
*	ڲ	
*
*	ز	
*
*	˵		SDAΪʱSCLһһӦź
************************************************************
*/
void IIC_NAck(void)
{
	
	SCL_L;						//SCL
	SDA_H;						//SDA
	DelayUs(iic_info.speed);
	SCL_H;						//SCL
	DelayUs(iic_info.speed);
	SCL_L;						//SCL
	
}

/*
************************************************************
*	ƣ	IIC_SendByte
*
*	ܣ	IICһֽ
*
*	ڲ	byteҪ͵ֽ
*
*	ز	
*
*	˵		
************************************************************
*/
void IIC_SendByte(unsigned char byte)
{

	unsigned char count = 0;
	
    SCL_L;							//ʱӿʼݴ
	
    for(; count < 8; count++)		//ѭ8Σÿηһbit
    {
		if(byte & 0x80)				//λ
			SDA_H;
		else
			SDA_L;
		
		byte <<= 1;					//byte1λ
		
		DelayUs(iic_info.speed);
		SCL_H;
		DelayUs(iic_info.speed);
		SCL_L;
    }

}

/*
************************************************************
*	ƣ	IIC_RecvByte
*
*	ܣ	IICһֽ
*
*	ڲ	
*
*	ز	յֽ
*
*	˵		
************************************************************
*/
unsigned char IIC_RecvByte(void)
{
	
	unsigned char count = 0, receive = 0;
	
	SDA_H;							//SDAߣ©״̬£Աȡ
	
    for(; count < 8; count++ )		//ѭ8Σÿηһbit
	{
		SCL_L;
		DelayUs(iic_info.speed);
		SCL_H;
		
        receive <<= 1;				//һλ
		
        if(SDA_R)					//SDAΪ1receiveÿǶbit0+1Ȼһѭһ
			receive++;
		
		DelayUs(iic_info.speed);
    }
	
    return receive;
	
}

/*
************************************************************
*	ƣ	I2C_WriteByte
*
*	ܣ	IICдһ
*
*	ڲ	slaveAddrӻַ
*				regAddrĴַ
*				byteҪд
*
*	ز	0-дɹ	1-дʧ
*
*	˵		*byteǻдݵıĵַΪЩĴֻҪ¼ĴҪдֵ
************************************************************
*/
_Bool I2C_WriteByte(unsigned char slaveAddr, unsigned char regAddr, unsigned char *byte)
{

	unsigned char addr = 0;

	addr = slaveAddr << 1;		//IICַ7bitҪ1λbit01-	0-д
	
	IIC_Start();				//ʼź
	
	IIC_SendByte(addr);			//豸ַ(д)
	if(IIC_WaitAck(5000))		//ȴӦ
		return IIC_Err;
	
	IIC_SendByte(regAddr);		//ͼĴַ
	if(IIC_WaitAck(5000))		//ȴӦ
		return IIC_Err;
	
	if(byte)
	{
		IIC_SendByte(*byte);	//
		if(IIC_WaitAck(5000))	//ȴӦ
			return IIC_Err;
	}
	
	IIC_Stop();					//ֹͣź
	
	return IIC_OK;

}

/*
************************************************************
*	ƣ	I2C_ReadByte
*
*	ܣ	IICȡһֽ
*
*	ڲ	slaveAddrӻַ
*				regAddrĴַ
*				valҪȡݻ
*
*	ز	0-ɹ		1-ʧ
*
*	˵		valһĵַ
************************************************************
*/
_Bool I2C_ReadByte(unsigned char slaveAddr, unsigned char regAddr, unsigned char *val)
{

	unsigned char addr = 0;

    addr = slaveAddr << 1;		//IICַ7bitҪ1λbit01-	0-д
	
	IIC_Start();				//ʼź
	
	IIC_SendByte(addr);			//豸ַ(д)
	if(IIC_WaitAck(5000))		//ȴӦ
		return IIC_Err;
	
	IIC_SendByte(regAddr);		//ͼĴַ
	if(IIC_WaitAck(5000))		//ȴӦ
		return IIC_Err;
	
	IIC_Start();				//ź
	
	IIC_SendByte(addr + 1);		//豸ַ()
	if(IIC_WaitAck(5000))		//ȴӦ
		return IIC_Err;
	
	*val = IIC_RecvByte();		//
	IIC_NAck();					//һӦźţȡ
	
	IIC_Stop();					//ֹͣź
	
	return IIC_OK;

}

/*
************************************************************
*	ƣ	I2C_WriteBytes
*
*	ܣ	IICд
*
*	ڲ	slaveAddrӻַ
*				regAddrĴַ
*				bufҪдݻ
*				numݳ
*
*	ز	0-дɹ	1-дʧ
*
*	˵		*bufһָһָ
************************************************************
*/
_Bool I2C_WriteBytes(unsigned char slaveAddr, unsigned char regAddr, unsigned char *buf, unsigned char num)
{

	unsigned char addr = 0;

	addr = slaveAddr << 1;		//IICַ7bitҪ1λbit01-	0-д
	
	IIC_Start();				//ʼź
	
	IIC_SendByte(addr);			//豸ַ(д)
	if(IIC_WaitAck(5000))		//ȴӦ
		return IIC_Err;
	
	IIC_SendByte(regAddr);		//ͼĴַ
	if(IIC_WaitAck(5000))		//ȴӦ
		return IIC_Err;
	
	while(num--)				//ѭд
	{
		IIC_SendByte(*buf);		//
		if(IIC_WaitAck(5000))	//ȴӦ
			return IIC_Err;
		
		buf++;					//ָƫƵһ
		
		DelayUs(10);
	}
	
	IIC_Stop();					//ֹͣź
	
	return IIC_OK;

}

/*
************************************************************
*	ƣ	I2C_ReadBytes
*
*	ܣ	IIC
*
*	ڲ	slaveAddrӻַ
*				regAddrĴַ
*				bufҪȡݻ
*				numݳ
*
*	ز	0-дɹ	1-дʧ
*
*	˵		*bufһָһָ
************************************************************
*/
_Bool I2C_ReadBytes(unsigned char slaveAddr, unsigned char regAddr, unsigned char *buf, unsigned char num)
{

	unsigned short addr = 0;

    addr = slaveAddr << 1;		//IICַ7bitҪ1λbit01-	0-д
	
	IIC_Start();				//ʼź
	
	IIC_SendByte(addr);			//豸ַ(д)
	if(IIC_WaitAck(5000))		//ȴӦ
		return IIC_Err;
	
	IIC_SendByte(regAddr);		//ͼĴַ
	if(IIC_WaitAck(5000))		//ȴӦ
		return IIC_Err;
	
	IIC_Start();				//ź
	
	IIC_SendByte(addr + 1);		//豸ַ()
	if(IIC_WaitAck(5000))		//ȴӦ
		return IIC_Err;
	
	while(num--)
	{
		*buf = IIC_RecvByte();
		buf++;					//ƫƵһݴ洢ַ
		
		if(num == 0)
        {
           IIC_NAck();			//һҪNOACK
        }
        else
        {
          IIC_Ack();			//ӦACK
		}
	}
	
	IIC_Stop();
	
	return IIC_OK;

}
