
#ifdef __cplusplus
extern "C" {
#endif 

#include "i2c.h"
#include "nvic.h"

static void I2C_delay()
{	
    volatile int i = 7;
    while (i)
        i--;
}

static int I2C_Start()
{
    SDA_H;
    SCL_H;
    I2C_delay();
    if (!SDA_read)
        return 0;
    SDA_L;
    I2C_delay();
    if (SDA_read)
        return 0;
    SDA_L;
    I2C_delay();
    return 1;
}

static void I2C_Stop()
{
    SCL_L;
    I2C_delay();
    SDA_L;
    I2C_delay();
    SCL_H;
    I2C_delay();
    SDA_H;
    I2C_delay();
} 

static void I2C_Ack()
{	
    SCL_L;
    I2C_delay();
    SDA_L;
    I2C_delay();
    SCL_H;
    I2C_delay();
    SCL_L;
    I2C_delay();
}   

static void I2C_NoAck()
{	
    SCL_L;
    I2C_delay();
    SDA_H;
    I2C_delay();
    SCL_H;
    I2C_delay();
    SCL_L;
    I2C_delay();
} 

static int I2C_WaitAck() 	
{
    SCL_L;
    I2C_delay();
    SDA_H;
    I2C_delay();
    SCL_H;
    I2C_delay();
    if (SDA_read) {
        SCL_L;
        return 0;
    }
    SCL_L;
    return 1;
}

static void I2C_SendByte(uint8_t b) 
{
    uint8_t i = 8;
    while (i--) {
        SCL_L;
        I2C_delay();
        if (b & 0x80)
            SDA_H;
        else
            SDA_L;
        b <<= 1;
        I2C_delay();
        SCL_H;
        I2C_delay();
    }
    SCL_L;
}  

static uint8_t I2C_ReadByteData()  
{ 
    uint8_t i = 8;
    uint8_t byte = 0;

    SDA_H;
    while (i--) {
        byte <<= 1;
        SCL_L;
        I2C_delay();
        SCL_H;
        I2C_delay();
        if (SDA_read) {
            byte |= 0x01;
        }
    }
    SCL_L;
    return byte;
} 

void I2C_InitGPIO(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
	//已更改
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

int I2C_WriteByte(uint8_t addr, uint8_t reg, uint8_t data)
{
    if (!I2C_Start())
        return 0;
    I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
    if (!I2C_WaitAck()) {
        I2C_Stop();
        return 0;
    }
    I2C_SendByte(reg);
    I2C_WaitAck();
    I2C_SendByte(data);
    if (!I2C_WaitAck()) {
        I2C_Stop();
        return 0;
    }
    I2C_Stop();
    return 1;
}	

int I2C_WriteBuf(uint8_t addr, uint8_t reg, uint8_t *data , uint8_t size)
{   
    int i;
    if (!I2C_Start())
        return 0;
    I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
    if (!I2C_WaitAck()) {
        I2C_Stop();
        return 0;
    }
    I2C_SendByte(reg);
    I2C_WaitAck();
    for (i = 0; i < size; i++) {
        I2C_SendByte(data[i]);
        if (!I2C_WaitAck()) {
            I2C_Stop();
            return 0;
        }
    }
    I2C_Stop();
    return 1;
}	

int I2C_ReadByte(uint8_t addr, uint8_t reg, uint8_t* data)
{
    if (!I2C_Start())
        return 0;
    I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
    if (!I2C_WaitAck()) {
        I2C_Stop();
        return 0;
    }
    I2C_SendByte(reg);
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte(addr << 1 | I2C_Direction_Receiver);
    I2C_WaitAck();
    *data = I2C_ReadByteData();
    I2C_NoAck();
    I2C_Stop();
    return 1;
}

int I2C_ReadBuf(uint8_t addr,uint8_t reg, uint8_t* data , uint8_t size)
{
    if (!I2C_Start())
        return 0;
    I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
    if (!I2C_WaitAck()) {
        I2C_Stop();
        return 0;
    }
    I2C_SendByte(reg);
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte(addr << 1 | I2C_Direction_Receiver);
    I2C_WaitAck();
    while (size) {
        *data = I2C_ReadByteData();
        if (size == 1)
            I2C_NoAck();
        else
            I2C_Ack();
        data++;
        size--;
    }
    I2C_Stop();
    return 1;
}	

#ifdef __cplusplus
}
#endif 

