반응형

STM32F10x series MCU를 사용하면서 제공되는 stm32f10x_i2c.h / stm32f10x_i2c.c 관련 STM32 library를 사용한 hardware I2C example code를 공유한다.

 

# i2c_hw.h

#ifndef __I2C_HW_H
#define __I2C_HW_H

/* includes */
#include "stm32f10x.h"
#include "hw_config.h"
/* defines */
/* functions */
void HW_I2C_master_initial(void);

uint8_t HW_I2C_Read(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToRead, uint8_t* pBuffer);
uint8_t HW_I2C_Write(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToWrite, uint8_t* pBuffer);
uint8_t I2C_Check_SlaveAddr(I2C_TypeDef* I2Cx, uint8_t DeviceAddr);

uint8_t HW_I2C_UTIL_Write(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t pBuffer);
uint8_t HW_I2C_UTIL_Read(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr);
void HW_I2C_UTIL_Write_Multi(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToWrite, uint8_t* pBuffer);
uint8_t HW_I2C_UTIL_Read_Multi(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t ReadCount, uint8_t (*pReadData));
uint8_t HW_I2C_UTIL_Check_SlaveAddr(I2C_TypeDef* I2Cx);

#endif  /* __I2C_HW_H */

 

# i2c_hw.c

#include "i2c_hw.h"

#define MAX_COMMUNICATION_FREQ   ((uint32_t) 400000)	// 100khz
#define FLAG_TIMEOUT             ((uint32_t)0x1000)
#define LONG_TIMEOUT             ((uint32_t)(10 * FLAG_TIMEOUT))

#define GPIO_I2C_HW        GPIOB

#define GPIO_I2C1_SCL	GPIO_Pin_6
#define GPIO_I2C1_SDA	GPIO_Pin_7
#define GPIO_I2C2_SCL	GPIO_Pin_10
#define GPIO_I2C2_SDA	GPIO_Pin_11

__IO uint32_t  UTIL_Timeout = LONG_TIMEOUT;
__IO uint16_t  UTIL_Address = 0;

void HW_I2C_master_initial(void)
{
	I2C_InitTypeDef 	I2C_InitStructure;
	GPIO_InitTypeDef	GPIO_InitStructure;

	// I2C_SCL_GPIO_CLK and I2C_SDA_GPIO_CLK Periph clock enable
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	// I2C Periph clock enable
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

	// Configure I2C pins: SCL , SDA
	GPIO_InitStructure.GPIO_Pin = GPIO_I2C1_SCL | GPIO_I2C1_SDA | GPIO_I2C2_SCL | GPIO_I2C2_SDA;;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
	GPIO_Init(GPIO_I2C_HW, &GPIO_InitStructure);

	// Free all used resources
	I2C_DeInit(I2C1);
	I2C_DeInit(I2C2);

	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
	I2C_InitStructure.I2C_OwnAddress1 = 0x00;
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	I2C_InitStructure.I2C_ClockSpeed = MAX_COMMUNICATION_FREQ;
	I2C_Init(I2C1, &I2C_InitStructure);
	I2C_Init(I2C2, &I2C_InitStructure);

	I2C_Cmd(I2C1, ENABLE);
	I2C_Cmd(I2C2, ENABLE);
}

uint8_t HW_I2C_Read(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToRead, uint8_t* pBuffer)
{
  __IO uint32_t UTIL_Timeout = LONG_TIMEOUT;
  __IO uint32_t temp;

  (void)(temp);

restart:

  UTIL_Timeout = LONG_TIMEOUT;
/* Send START condition */
  I2C_GenerateSTART(I2Cx, ENABLE);
  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if (UTIL_Timeout-- == 0)
      return ERROR;
  }

  UTIL_Timeout = LONG_TIMEOUT;
  /* Send slave address for read */
  I2C_Send7bitAddress(I2Cx, DeviceAddr, I2C_Direction_Transmitter);

  while (!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if (UTIL_Timeout-- == 0)
    {
      I2C_ClearFlag(I2Cx,I2C_FLAG_BUSY|I2C_FLAG_AF);
      goto restart;
    }
  }
  /* Clear EV6 by setting again the PE bit */
  I2C_Cmd(I2Cx, ENABLE);

  I2C_SendData(I2Cx, RegisterAddr);

  /* Test on EV8 and clear it */
  UTIL_Timeout = LONG_TIMEOUT;
  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
    if (UTIL_Timeout-- == 0)
     return ERROR;
  }

  if (NumByteToRead == 0x01)
  {
    restart3:
    /* Send START condition */
    I2C_GenerateSTART(I2Cx, ENABLE);
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
    /* Send Slave address for read */
    I2C_Send7bitAddress(I2Cx, DeviceAddr, I2C_Direction_Receiver);
    /* Wait until ADDR is set */
    UTIL_Timeout = LONG_TIMEOUT;
    while (!I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR))
    {
      if (UTIL_Timeout-- == 0)
      {
        I2C_ClearFlag(I2Cx,I2C_FLAG_BUSY|I2C_FLAG_AF);
        goto restart3;
      }
    }
    /* Clear ACK */
    I2C_AcknowledgeConfig(I2Cx, DISABLE);
    __disable_irq();
    /* Clear ADDR flag */
    temp = I2Cx->SR2;
    /* Program the STOP */
    I2C_GenerateSTOP(I2Cx, ENABLE);
    __enable_irq();
    while ((I2C_GetLastEvent(I2Cx) & 0x0040) != 0x000040); /* Poll on RxNE */
    /* Read the data */
    *pBuffer = I2C_ReceiveData(I2Cx);
    /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
    while ((I2Cx->CR1&0x200) == 0x200);
    /* Enable Acknowledgement to be ready for another reception */
    I2C_AcknowledgeConfig(I2Cx, ENABLE);

    return SUCCESS;
  }
  else
    if(NumByteToRead == 0x02)
    {
      restart4:
      /* Send START condition */
      I2C_GenerateSTART(I2Cx, ENABLE);
      while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
      /* Send EEPROM address for read */
      I2C_Send7bitAddress(I2Cx, DeviceAddr, I2C_Direction_Receiver);
      I2Cx->CR1 = 0xC01; /* ACK=1; POS =1 */
      UTIL_Timeout = LONG_TIMEOUT;
      while (!I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR))
      {
        if (UTIL_Timeout-- == 0)
        {
          I2C_ClearFlag(I2Cx,I2C_FLAG_BUSY|I2C_FLAG_AF);
          goto restart4;
        }
      }
      __disable_irq();
      /* Clear ADDR */
      temp = I2Cx->SR2;
      /* Disable ACK */
      I2C_AcknowledgeConfig(I2Cx, DISABLE);
      __enable_irq();
      while ((I2C_GetLastEvent(I2Cx) & 0x0004) != 0x00004); /* Poll on BTF */

       __disable_irq();
      /* Program the STOP */
      I2C_GenerateSTOP(I2Cx, ENABLE);
      /* Read first data */
      *pBuffer = I2Cx->DR;
      pBuffer++;
      /* Read second data */
      *pBuffer = I2Cx->DR;
      __enable_irq();
      I2Cx->CR1 = 0x0401; /* POS = 0, ACK = 1, PE = 1 */

      return SUCCESS;
    }
  else
  {
restart2:
    UTIL_Timeout = LONG_TIMEOUT;
    /* Send START condition */
    I2C_GenerateSTART(I2Cx, ENABLE);
    /* Test on EV5 and clear it */
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
    {
      if (UTIL_Timeout-- == 0) return ERROR;
    }
    UTIL_Timeout = LONG_TIMEOUT;
    /* Send slave address for read */
    I2C_Send7bitAddress(I2Cx,  DeviceAddr, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
    {

      if (UTIL_Timeout-- == 0)
      {
        I2C_ClearFlag(I2Cx,I2C_FLAG_BUSY|I2C_FLAG_AF);
        goto restart2;
      }
    }

    /* While there is data to be read; here the safe procedure is implemented */
    while (NumByteToRead)
    {

      if (NumByteToRead != 3) /* Receive bytes from first byte until byte N-3 */
      {
        while ((I2C_GetLastEvent(I2Cx) & 0x00004) != 0x000004); /* Poll on BTF */
        /* Read data */
        *pBuffer = I2C_ReceiveData(I2Cx);
        pBuffer++;
        /* Decrement the read bytes counter */
        NumByteToRead--;
      }

      if (NumByteToRead == 3)  /* it remains to read three data: data N-2, data N-1, Data N */
      {

        /* Data N-2 in DR and data N -1 in shift register */
        while ((I2C_GetLastEvent(I2Cx) & 0x000004) != 0x0000004); /* Poll on BTF */
        /* Clear ACK */
        I2C_AcknowledgeConfig(I2Cx, DISABLE);
        __disable_irq();
        /* Read Data N-2 */
        *pBuffer = I2C_ReceiveData(I2Cx);
        pBuffer++;
        /* Program the STOP */
        I2C_GenerateSTOP(I2Cx, ENABLE);
        /* Read DataN-1 */
        *pBuffer = I2C_ReceiveData(I2Cx);
        __enable_irq();
        pBuffer++;
        while ((I2C_GetLastEvent(I2Cx) & 0x00000040) != 0x0000040); /* Poll on RxNE */
        /* Read DataN */
        *pBuffer = I2Cx->DR;
        /* Reset the number of bytes to be read by master */
        NumByteToRead = 0;
      }
    }
    /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
    while ((I2Cx->CR1&0x200) == 0x200);
    /* Enable Acknowledgement to be ready for another reception */
    I2C_AcknowledgeConfig(I2Cx, ENABLE);

    return SUCCESS;
  }
}

uint8_t HW_I2C_Write(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr,
                               uint16_t NumByteToWrite,
                               uint8_t* pBuffer)
{

 restart1:
  UTIL_Timeout = LONG_TIMEOUT;
  /* Send START condition */
  I2C_GenerateSTART(I2Cx, ENABLE);
  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if (UTIL_Timeout-- == 0) return ERROR;
  }
  /* Send slave address for write */
  I2C_Send7bitAddress(I2Cx, DeviceAddr, I2C_Direction_Transmitter);

  UTIL_Timeout = LONG_TIMEOUT;
  /* Test on EV6 and clear it */
  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {

    if (UTIL_Timeout-- == 0)
    {
      I2C_ClearFlag(I2Cx,I2C_FLAG_BUSY|I2C_FLAG_AF);
      goto restart1;
    }
  }

  UTIL_Timeout = LONG_TIMEOUT;

  /* Transmit the first address for r/w operations */
  I2C_SendData(I2Cx, RegisterAddr);

  /* Test on EV8 and clear it */
  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
    if (UTIL_Timeout-- == 0)
      return ERROR;
  }
  if (NumByteToWrite == 0x01)
  {
    UTIL_Timeout = LONG_TIMEOUT;
    /* Prepare the register value to be sent */
    I2C_SendData(I2Cx, *pBuffer);

    /* Test on EV8 and clear it */
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
    {
      if (UTIL_Timeout-- == 0)
        return ERROR;
    }

    /* End the configuration sequence */
    I2C_GenerateSTOP(I2Cx, ENABLE);
    return SUCCESS;
  }
  I2C_SendData(I2Cx, *pBuffer);
  pBuffer++;
  NumByteToWrite--;
  /* While there is data to be written */
  while (NumByteToWrite--)
  {
    while ((I2C_GetLastEvent(I2Cx) & 0x04) != 0x04);  /* Poll on BTF */
    /* Send the current byte */
    I2C_SendData(I2Cx, *pBuffer);
    /* Point to the next byte to be written */
    pBuffer++;

  }
  UTIL_Timeout = LONG_TIMEOUT;
  /* Test on EV8_2 and clear it, BTF = TxE = 1, DR and shift registers are
   empty */
  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
    if (UTIL_Timeout-- == 0) return ERROR;
  }
  /* Send STOP condition */
  I2C_GenerateSTOP(I2Cx, ENABLE);
  return SUCCESS;
}

uint8_t I2C_Check_SlaveAddr(I2C_TypeDef* I2Cx, uint8_t DeviceAddr)
{
	uint8_t   returnack = SUCCESS;

	UTIL_Timeout = FLAG_TIMEOUT;
	/* Send START condition */
	I2C_GenerateSTART(I2Cx, ENABLE);
	/* Test on EV5 and clear it */
	while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
	{
		if (UTIL_Timeout-- == 0) return ERROR;
	}
	/* Send slave address for write */
	I2C_Send7bitAddress(I2Cx, DeviceAddr, I2C_Direction_Transmitter);

	UTIL_Timeout = FLAG_TIMEOUT;
	/* Test on EV6 and clear it */
	while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
	{

		if (UTIL_Timeout-- == 0)
		{
		  I2C_ClearFlag(I2Cx,I2C_FLAG_BUSY|I2C_FLAG_AF);
		  returnack = ERROR;
		  break;
		}
	}
	I2C_GenerateSTOP(I2Cx, ENABLE);

	return returnack;
}

uint8_t HW_I2C_UTIL_Write(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t pBuffer)
{
	return HW_I2C_Write(I2Cx, DeviceAddr<<1,RegisterAddr,1,&pBuffer);
}

uint8_t HW_I2C_UTIL_Read(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr)
{
	uint8_t	pBuffer;

	HW_I2C_Read(I2Cx, DeviceAddr<<1,RegisterAddr,1,&pBuffer);

	return pBuffer;
}

void HW_I2C_UTIL_Write_Multi(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToWrite, uint8_t* pBuffer)
{
	HW_I2C_Write(I2Cx, DeviceAddr<<1,RegisterAddr,NumByteToWrite,pBuffer);
}

uint8_t HW_I2C_UTIL_Read_Multi(I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t ReadCount, uint8_t (*pReadData))
{
	HW_I2C_Read(I2Cx, DeviceAddr<<1,RegisterAddr,ReadCount,pReadData);

	return 1;
}

uint8_t HW_I2C_UTIL_Check_SlaveAddr(I2C_TypeDef* I2Cx)
{
	uint8_t i = 0x00;

	for(i = 0; i < 255; i++)
	{
		if(I2C_Check_SlaveAddr(I2Cx, i) == SUCCESS)
		{
			return i;
		}
	}
	return i;
}
반응형
반응형

STM32F10x series MCU를 사용하면서 device의 slave address가 겹치는 2개 이상의 여러 개의 I2C를 제어할 필요가 있을 때 100kHz to 400kHz clock speed 수준의 software I2C example code를 공유한다.

 

참고로 only GPIO으로만 control 하기 때문에 stm32f10x_i2c.h / stm32f10x_i2c.c 관련 STM32 library는 없어도 된다. 그리고 software I2C channel별 GPIO 설정(GPIOC PIN0 , GPIOC PIN14 등)은 user가 임의로 설정하면 된다.

 

# i2c_sw.h

#ifndef __I2C_SW_H
#define __I2C_SW_H

/* includes */
#include "stm32f10x.h"
#include "stdio.h"

/* defines */
#define GPIO_SW_I2C1_SCL           GPIOC
#define GPIO_SW_I2C1_SCL_PIN   GPIO_Pin_0
#define GPIO_SW_I2C1_SDA           GPIOB
#define GPIO_SW_I2C1_SDA_PIN   GPIO_Pin_14

#define GPIO_SW_I2C2_SCL           GPIOB
#define GPIO_SW_I2C2_SCL_PIN   GPIO_Pin_1
#define GPIO_SW_I2C2_SDA           GPIOC
#define GPIO_SW_I2C2_SDA_PIN   GPIO_Pin_1

#define GPIO_SW_I2C3_SCL           GPIOB
#define GPIO_SW_I2C3_SCL_PIN   GPIO_Pin_6
#define GPIO_SW_I2C3_SDA           GPIOB
#define GPIO_SW_I2C3_SDA_PIN   GPIO_Pin_7

#define GPIO_SW_I2C4_SCL GPIOB
#define GPIO_SW_I2C4_SCL_PIN GPIO_Pin_10
#define GPIO_SW_I2C4_SDA GPIOB
#define GPIO_SW_I2C4_SDA_PIN GPIO_Pin_11

#define GPIO_SW_I2C5_SCL           GPIOC
#define GPIO_SW_I2C5_SCL_PIN   GPIO_Pin_6
#define GPIO_SW_I2C5_SDA           GPIOC
#define GPIO_SW_I2C5_SDA_PIN   GPIO_Pin_5

#define GPIO_SW_I2C6_SCL           GPIOA
#define GPIO_SW_I2C6_SCL_PIN   GPIO_Pin_6
#define GPIO_SW_I2C6_SDA           GPIOC
#define GPIO_SW_I2C6_SDA_PIN   GPIO_Pin_8

#define GPIO_SW_I2C7_SCL           GPIOC
#define GPIO_SW_I2C7_SCL_PIN   GPIO_Pin_10
#define GPIO_SW_I2C7_SDA           GPIOA
#define GPIO_SW_I2C7_SDA_PIN   GPIO_Pin_1

#define GPIO_SW_I2C8_SCL           GPIOC
#define GPIO_SW_I2C8_SCL_PIN   GPIO_Pin_12
#define GPIO_SW_I2C8_SDA           GPIOC
#define GPIO_SW_I2C8_SDA_PIN   GPIO_Pin_11

#define GPIO_SW_I2C9_SCL           GPIOB
#define GPIO_SW_I2C9_SCL_PIN   GPIO_Pin_12
#define GPIO_SW_I2C9_SDA           GPIOA
#define GPIO_SW_I2C9_SDA_PIN   GPIO_Pin_5

#define GPIO_SW_I2C10_SCL           GPIOB
#define GPIO_SW_I2C10_SCL_PIN   GPIO_Pin_12
#define GPIO_SW_I2C10_SDA           GPIOA
#define GPIO_SW_I2C10_SDA_PIN   GPIO_Pin_5

#define SW_I2C1		1
#define SW_I2C2		2
#define SW_I2C3		3
#define SW_I2C4		4
#define SW_I2C5		5
#define SW_I2C6		6
#define SW_I2C7		7
#define SW_I2C8		8
#define SW_I2C9		9
#define SW_I2C10	10

/* functions */
void SW_I2C_initial(void);

void i2c_port_initial(uint8_t sel);		

uint8_t SW_I2C_ReadVal_SDA(uint8_t sel);

void SW_I2C_Write_Data(uint8_t sel, uint8_t data);
uint8_t SW_I2C_Read_Data(uint8_t sel);

uint8_t SW_I2C_WriteControl_8Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint8_t data);
uint8_t SW_I2C_WriteControl_8Bit_OnlyRegAddr(uint8_t sel, uint8_t IICID, uint8_t regaddr);
uint8_t SW_I2C_WriteControl_16Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint16_t data);

uint8_t SW_I2C_ReadControl_8Bit_OnlyRegAddr(uint8_t sel, uint8_t IICID, uint8_t regaddr);
uint8_t SW_I2C_ReadControl_8Bit_OnlyData(uint8_t sel, uint8_t IICID);
uint16_t SW_I2C_ReadControl_16Bit_OnlyData(uint8_t sel, uint8_t IICID);
uint8_t SW_I2C_ReadControl_8Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr);
uint16_t SW_I2C_ReadControl_16Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr);

uint8_t SW_I2C_ReadnControl_8Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint8_t rcnt, uint8_t (*pdata));
uint8_t SW_I2C_Multi_ReadnControl_8Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint8_t rcnt, uint8_t (*pdata));
uint8_t SW_I2C_Check_SlaveAddr(uint8_t sel, uint8_t IICID);

uint8_t SW_I2C_UTIL_WRITE(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint8_t data);
uint8_t SW_I2C_UTIL_Read(uint8_t sel, uint8_t IICID, uint8_t regaddr);
uint8_t SW_I2C_UTIL_Read_Multi(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint8_t rcnt, uint8_t (*pdata));

#endif  /* __I2C_SW_H */

 

# i2c_sw.c

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "hw_config.h"

//#define  SW_I2C_WAIT_TIME  26	//100Khz(11.4us)
//#define  SW_I2C_WAIT_TIME  25	//(11.0us)
//#define  SW_I2C_WAIT_TIME  23	//(10.4us)
#define  SW_I2C_WAIT_TIME  22	//100Khz(10.0us)	100Khz	==	10us
//#define  SW_I2C_WAIT_TIME  10	//195Khz
//#define  SW_I2C_WAIT_TIME  9	//205Khz	200Khz	==	5us
//#define  SW_I2C_WAIT_TIME  8	//237Khz
//#define  SW_I2C_WAIT_TIME  7	//240Khz	250Khz	==	4us
//#define  SW_I2C_WAIT_TIME  6	//275Khz
//#define  SW_I2C_WAIT_TIME  5	//305Khz
//#define  SW_I2C_WAIT_TIME  4	//350Khz(3.84us)
//#define  SW_I2C_WAIT_TIME  3	//400Khz(3.44us)
//#define  SW_I2C_WAIT_TIME  2	//425Khz(3.04us)	333Khz	==	3us
//#define  SW_I2C_WAIT_TIME  1	//425Khz(2.64us)	400Khz	==	2.5us

#define  I2C_READ       0x01
#define  READ_CMD       1
#define  WRITE_CMD      0

#define SW_I2C1_SCL_GPIO  GPIO_SW_I2C1_SCL
#define SW_I2C1_SDA_GPIO  GPIO_SW_I2C1_SDA
#define SW_I2C1_SCL_PIN   GPIO_SW_I2C1_SCL_PIN
#define SW_I2C1_SDA_PIN   GPIO_SW_I2C1_SDA_PIN

#define SW_I2C2_SCL_GPIO  GPIO_SW_I2C2_SCL
#define SW_I2C2_SDA_GPIO  GPIO_SW_I2C2_SDA
#define SW_I2C2_SCL_PIN   GPIO_SW_I2C2_SCL_PIN
#define SW_I2C2_SDA_PIN   GPIO_SW_I2C2_SDA_PIN

#define SW_I2C3_SCL_GPIO  GPIO_SW_I2C3_SCL
#define SW_I2C3_SDA_GPIO  GPIO_SW_I2C3_SDA
#define SW_I2C3_SCL_PIN   GPIO_SW_I2C3_SCL_PIN
#define SW_I2C3_SDA_PIN   GPIO_SW_I2C3_SDA_PIN

#define SW_I2C4_SCL_GPIO  GPIO_SW_I2C4_SCL
#define SW_I2C4_SDA_GPIO  GPIO_SW_I2C4_SDA
#define SW_I2C4_SCL_PIN   GPIO_SW_I2C4_SCL_PIN
#define SW_I2C4_SDA_PIN   GPIO_SW_I2C4_SDA_PIN

#define SW_I2C5_SCL_GPIO  GPIO_SW_I2C5_SCL
#define SW_I2C5_SDA_GPIO  GPIO_SW_I2C5_SDA
#define SW_I2C5_SCL_PIN   GPIO_SW_I2C5_SCL_PIN
#define SW_I2C5_SDA_PIN   GPIO_SW_I2C5_SDA_PIN

#define SW_I2C6_SCL_GPIO  GPIO_SW_I2C6_SCL
#define SW_I2C6_SDA_GPIO  GPIO_SW_I2C6_SDA
#define SW_I2C6_SCL_PIN   GPIO_SW_I2C6_SCL_PIN
#define SW_I2C6_SDA_PIN   GPIO_SW_I2C6_SDA_PIN

#define SW_I2C7_SCL_GPIO  GPIO_SW_I2C7_SCL
#define SW_I2C7_SDA_GPIO  GPIO_SW_I2C7_SDA
#define SW_I2C7_SCL_PIN   GPIO_SW_I2C7_SCL_PIN
#define SW_I2C7_SDA_PIN   GPIO_SW_I2C7_SDA_PIN

#define SW_I2C8_SCL_GPIO  GPIO_SW_I2C8_SCL
#define SW_I2C8_SDA_GPIO  GPIO_SW_I2C8_SDA
#define SW_I2C8_SCL_PIN   GPIO_SW_I2C8_SCL_PIN
#define SW_I2C8_SDA_PIN   GPIO_SW_I2C8_SDA_PIN

#define SW_I2C9_SCL_GPIO  GPIO_SW_I2C9_SCL
#define SW_I2C9_SDA_GPIO  GPIO_SW_I2C9_SDA
#define SW_I2C9_SCL_PIN   GPIO_SW_I2C9_SCL_PIN
#define SW_I2C9_SDA_PIN   GPIO_SW_I2C9_SDA_PIN

#define SW_I2C10_SCL_GPIO  GPIO_SW_I2C10_SCL
#define SW_I2C10_SDA_GPIO  GPIO_SW_I2C10_SDA
#define SW_I2C10_SCL_PIN   GPIO_SW_I2C10_SCL_PIN
#define SW_I2C10_SDA_PIN   GPIO_SW_I2C10_SDA_PIN

void TIMER__Wait_us(__IO u32 nCount)
{
    for (; nCount != 0;nCount--);
}

/* internal static functions */
void SW_I2C_initial(void)
{
	GPIO_InitTypeDef			GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;

    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C1_SCL_PIN;
    GPIO_Init(GPIO_SW_I2C1_SCL, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C1_SDA_PIN;
    GPIO_Init(GPIO_SW_I2C1_SDA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C2_SCL_PIN;
    GPIO_Init(GPIO_SW_I2C2_SCL, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C2_SDA_PIN;
    GPIO_Init(GPIO_SW_I2C2_SDA, &GPIO_InitStructure);
	
    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C3_SCL_PIN;
    GPIO_Init(GPIO_SW_I2C3_SCL, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C3_SDA_PIN;
    GPIO_Init(GPIO_SW_I2C3_SDA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C4_SCL_PIN;
    GPIO_Init(GPIO_SW_I2C4_SCL, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C4_SDA_PIN;
    GPIO_Init(GPIO_SW_I2C4_SDA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C5_SCL_PIN;
    GPIO_Init(GPIO_SW_I2C5_SCL, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C5_SDA_PIN;
    GPIO_Init(GPIO_SW_I2C5_SDA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C6_SCL_PIN;
    GPIO_Init(GPIO_SW_I2C6_SCL, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C6_SDA_PIN;
    GPIO_Init(GPIO_SW_I2C6_SDA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C7_SCL_PIN;
    GPIO_Init(GPIO_SW_I2C7_SCL, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C7_SDA_PIN;
    GPIO_Init(GPIO_SW_I2C7_SDA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C8_SCL_PIN;
    GPIO_Init(GPIO_SW_I2C8_SCL, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C8_SDA_PIN;
    GPIO_Init(GPIO_SW_I2C8_SDA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C9_SCL_PIN;
    GPIO_Init(GPIO_SW_I2C9_SCL, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin   = GPIO_SW_I2C9_SDA_PIN;
    GPIO_Init(GPIO_SW_I2C9_SDA, &GPIO_InitStructure);

}

// SDA High
void sda_high(uint8_t sel)
{
    if(sel == 1)
        GPIO_SetBits(SW_I2C1_SDA_GPIO, SW_I2C1_SDA_PIN);
    else if(sel == 2)
        GPIO_SetBits(SW_I2C2_SDA_GPIO, SW_I2C2_SDA_PIN);		
    else if(sel == 3)
        GPIO_SetBits(SW_I2C3_SDA_GPIO, SW_I2C3_SDA_PIN);
    else if(sel == 4)
        GPIO_SetBits(SW_I2C4_SDA_GPIO, SW_I2C4_SDA_PIN);
    else if(sel == 5)
        GPIO_SetBits(SW_I2C5_SDA_GPIO, SW_I2C5_SDA_PIN);
    else if(sel == 6)
        GPIO_SetBits(SW_I2C6_SDA_GPIO, SW_I2C6_SDA_PIN);		
    else if(sel == 7)
        GPIO_SetBits(SW_I2C7_SDA_GPIO, SW_I2C7_SDA_PIN);
    else if(sel == 8)
        GPIO_SetBits(SW_I2C8_SDA_GPIO, SW_I2C8_SDA_PIN);
    else if(sel == 9)
        GPIO_SetBits(SW_I2C9_SDA_GPIO, SW_I2C9_SDA_PIN);
    else if(sel == 10)
        GPIO_SetBits(SW_I2C10_SDA_GPIO, SW_I2C10_SDA_PIN);
}

// SDA low
void sda_low(uint8_t sel)
{
    if(sel == 1)
        GPIO_ResetBits(SW_I2C1_SDA_GPIO, SW_I2C1_SDA_PIN);
    else if(sel == 2)
	GPIO_ResetBits(SW_I2C2_SDA_GPIO, SW_I2C2_SDA_PIN);	
    else if(sel == 3)
	GPIO_ResetBits(SW_I2C3_SDA_GPIO, SW_I2C3_SDA_PIN);
    else if(sel == 4)
	GPIO_ResetBits(SW_I2C4_SDA_GPIO, SW_I2C4_SDA_PIN);
    else if(sel == 5)
	GPIO_ResetBits(SW_I2C5_SDA_GPIO, SW_I2C5_SDA_PIN);
    else if(sel == 6)
	GPIO_ResetBits(SW_I2C6_SDA_GPIO, SW_I2C6_SDA_PIN);	
    else if(sel == 7)
	GPIO_ResetBits(SW_I2C7_SDA_GPIO, SW_I2C7_SDA_PIN);
    else if(sel == 8)
	GPIO_ResetBits(SW_I2C8_SDA_GPIO, SW_I2C8_SDA_PIN);
    else if(sel == 9)
	GPIO_ResetBits(SW_I2C9_SDA_GPIO, SW_I2C9_SDA_PIN);
    else if(sel == 10)
	GPIO_ResetBits(SW_I2C10_SDA_GPIO, SW_I2C10_SDA_PIN);
}

// SCL High
void scl_high(uint8_t sel)
{
    if(sel == 1)
        GPIO_SetBits(SW_I2C1_SCL_GPIO, SW_I2C1_SCL_PIN);
    else if(sel == 2)
        GPIO_SetBits(SW_I2C2_SCL_GPIO, SW_I2C2_SCL_PIN);
    else if(sel == 3)
        GPIO_SetBits(SW_I2C3_SCL_GPIO, SW_I2C3_SCL_PIN);
    else if(sel == 4)
        GPIO_SetBits(SW_I2C4_SCL_GPIO, SW_I2C4_SCL_PIN);
    else if(sel == 5)
        GPIO_SetBits(SW_I2C5_SCL_GPIO, SW_I2C5_SCL_PIN);
    else if(sel == 6)
        GPIO_SetBits(SW_I2C6_SCL_GPIO, SW_I2C6_SCL_PIN);
    else if(sel == 7)
        GPIO_SetBits(SW_I2C7_SCL_GPIO, SW_I2C7_SCL_PIN);
    else if(sel == 8)
        GPIO_SetBits(SW_I2C8_SCL_GPIO, SW_I2C8_SCL_PIN);
    else if(sel == 9)
        GPIO_SetBits(SW_I2C9_SCL_GPIO, SW_I2C9_SCL_PIN);
    else if(sel == 10)
        GPIO_SetBits(SW_I2C10_SCL_GPIO, SW_I2C10_SCL_PIN);
}

// SCL low
void scl_low(uint8_t sel)
{
    if(sel == 1)
        GPIO_ResetBits(SW_I2C1_SCL_GPIO, SW_I2C1_SCL_PIN);
    else if(sel == 2)
        GPIO_ResetBits(SW_I2C2_SCL_GPIO, SW_I2C2_SCL_PIN);
    else if(sel == 3)
        GPIO_ResetBits(SW_I2C3_SCL_GPIO, SW_I2C3_SCL_PIN);
    else if(sel == 4)
        GPIO_ResetBits(SW_I2C4_SCL_GPIO, SW_I2C4_SCL_PIN);
    else if(sel == 5)
        GPIO_ResetBits(SW_I2C5_SCL_GPIO, SW_I2C5_SCL_PIN);
    else if(sel == 6)
        GPIO_ResetBits(SW_I2C6_SCL_GPIO, SW_I2C6_SCL_PIN);
    else if(sel == 7)
        GPIO_ResetBits(SW_I2C7_SCL_GPIO, SW_I2C7_SCL_PIN);
    else if(sel == 8)
        GPIO_ResetBits(SW_I2C8_SCL_GPIO, SW_I2C8_SCL_PIN);
    else if(sel == 9)
        GPIO_ResetBits(SW_I2C9_SCL_GPIO, SW_I2C9_SCL_PIN);
    else if(sel == 10)
        GPIO_ResetBits(SW_I2C10_SCL_GPIO, SW_I2C10_SCL_PIN);
}

void sda_out(uint8_t sel, uint8_t out)
{
    if (out)
    {
        sda_high(sel);
    }
    else
    {
        sda_low(sel);
    }
}

void sda_in_mode(uint8_t sel)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;	//IPD->IPU
		
    if(sel == 1)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C1_SDA_PIN;
        GPIO_Init(SW_I2C1_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 2)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C2_SDA_PIN;
        GPIO_Init(SW_I2C2_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 3)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C3_SDA_PIN;
        GPIO_Init(SW_I2C3_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 4)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C4_SDA_PIN;
        GPIO_Init(SW_I2C4_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 5)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C5_SDA_PIN;
        GPIO_Init(SW_I2C5_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 6)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C6_SDA_PIN;
        GPIO_Init(SW_I2C6_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 7)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C7_SDA_PIN;
        GPIO_Init(SW_I2C7_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 8)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C8_SDA_PIN;
        GPIO_Init(SW_I2C8_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 9)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C9_SDA_PIN;
        GPIO_Init(SW_I2C9_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 10)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C10_SDA_PIN;
        GPIO_Init(SW_I2C10_SDA_GPIO, &GPIO_InitStructure);
    }
}

void sda_out_mode(uint8_t sel)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_OD;		// error point GPIO_Mode_Out_PP
		
    if(sel == 1)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C1_SDA_PIN;
        GPIO_Init(SW_I2C1_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 2)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C2_SDA_PIN;
        GPIO_Init(SW_I2C2_SDA_GPIO, &GPIO_InitStructure);
    }		
    else if(sel == 3)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C3_SDA_PIN;
        GPIO_Init(SW_I2C3_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 4)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C4_SDA_PIN;
        GPIO_Init(SW_I2C4_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 5)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C5_SDA_PIN;
        GPIO_Init(SW_I2C5_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 6)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C6_SDA_PIN;
        GPIO_Init(SW_I2C6_SDA_GPIO, &GPIO_InitStructure);
    }		
    else if(sel == 7)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C7_SDA_PIN;
        GPIO_Init(SW_I2C7_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 8)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C8_SDA_PIN;
        GPIO_Init(SW_I2C8_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 9)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C9_SDA_PIN;
        GPIO_Init(SW_I2C9_SDA_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 10)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C10_SDA_PIN;
        GPIO_Init(SW_I2C10_SDA_GPIO, &GPIO_InitStructure);
    }
}

void scl_in_mode(uint8_t sel)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;	//IPD->IPU
		
    if(sel == 1)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C1_SCL_PIN;
        GPIO_Init(SW_I2C1_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 2)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C2_SCL_PIN;
        GPIO_Init(SW_I2C2_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 3)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C3_SCL_PIN;
        GPIO_Init(SW_I2C3_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 4)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C4_SCL_PIN;
        GPIO_Init(SW_I2C4_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 5)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C5_SCL_PIN;
        GPIO_Init(SW_I2C5_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 6)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C6_SCL_PIN;
        GPIO_Init(SW_I2C6_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 7)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C7_SCL_PIN;
        GPIO_Init(SW_I2C7_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 8)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C8_SCL_PIN;
        GPIO_Init(SW_I2C8_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 9)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C9_SCL_PIN;
        GPIO_Init(SW_I2C9_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 10)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C10_SCL_PIN;
        GPIO_Init(SW_I2C10_SCL_GPIO, &GPIO_InitStructure);
    }
}

void scl_out_mode(uint8_t sel)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_OD;		// error point GPIO_Mode_Out_PP
		
    if(sel == 1)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C1_SCL_PIN;
        GPIO_Init(SW_I2C1_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 2)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C2_SCL_PIN;
        GPIO_Init(SW_I2C2_SCL_GPIO, &GPIO_InitStructure);
    }		
    else if(sel == 3)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C3_SCL_PIN;
        GPIO_Init(SW_I2C3_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 4)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C4_SCL_PIN;
        GPIO_Init(SW_I2C4_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 5)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C5_SCL_PIN;
        GPIO_Init(SW_I2C5_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 6)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C6_SCL_PIN;
        GPIO_Init(SW_I2C6_SCL_GPIO, &GPIO_InitStructure);
    }		
    else if(sel == 7)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C7_SCL_PIN;
        GPIO_Init(SW_I2C7_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 8)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C8_SCL_PIN;
        GPIO_Init(SW_I2C8_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 9)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C9_SCL_PIN;
        GPIO_Init(SW_I2C9_SCL_GPIO, &GPIO_InitStructure);
    }
    else if(sel == 10)
    {
        GPIO_InitStructure.GPIO_Pin   = SW_I2C10_SCL_PIN;
        GPIO_Init(SW_I2C10_SCL_GPIO, &GPIO_InitStructure);
    }
}

void i2c_clk_data_out(uint8_t sel)
{
    scl_high(sel);
    TIMER__Wait_us(SW_I2C_WAIT_TIME);
    scl_low(sel);
//    TIMER__Wait_us(SW_I2C_WAIT_TIME>>2);
}

void i2c_port_initial(uint8_t sel)
{
    sda_high(sel);
    scl_high(sel);
}

void i2c_start_condition(uint8_t sel)
{
    sda_high(sel);
    scl_high(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME);
    sda_low(sel);
    TIMER__Wait_us(SW_I2C_WAIT_TIME);
    scl_low(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME << 1);
}

void i2c_stop_condition(uint8_t sel)
{
    sda_low(sel);
    scl_high(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME);
    sda_high(sel);
    TIMER__Wait_us(SW_I2C_WAIT_TIME);
}

uint8_t i2c_check_ack(uint8_t sel)
{
    uint8_t         ack;
    int             i;
    unsigned int    temp;

    sda_in_mode(sel);

    scl_high(sel);

    ack = FALSE;
    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    for (i = 10; i > 0; i--)
    {
        temp = !(SW_I2C_ReadVal_SDA(sel));	//0=ack , 1=nack
        if (temp)	// if ack, enter
        {
            ack = TRUE;
            break;
        }
    }
    scl_low(sel);
    sda_out_mode(sel);	//during setting, sda signal high

    TIMER__Wait_us(SW_I2C_WAIT_TIME);
    return ack;
}

void i2c_check_not_ack(uint8_t sel)
{
    sda_in_mode(sel);
    i2c_clk_data_out(sel);
    sda_out_mode(sel);
    TIMER__Wait_us(SW_I2C_WAIT_TIME);
}

void i2c_check_not_ack_continue(uint8_t sel)
{
//    sda_in_mode();
    i2c_clk_data_out(sel);
//    sda_out_mode();
    TIMER__Wait_us(SW_I2C_WAIT_TIME);
}

void i2c_slave_address(uint8_t sel, uint8_t IICID, uint8_t readwrite)
{
    int x;

    if (readwrite)
    {
        IICID |= I2C_READ;
    }
    else
    {
        IICID &= ~I2C_READ;
    }

    scl_low(sel);

    for (x = 7; x >= 0; x--)
    {
        sda_out(sel, IICID & (1 << x));
        TIMER__Wait_us(SW_I2C_WAIT_TIME);
        i2c_clk_data_out(sel);
//        TIMER__Wait_us(SW_I2C_WAIT_TIME);
    }
}

void i2c_register_address(uint8_t sel, uint8_t addr)
{
    int  x;

    scl_low(sel);

    for (x = 7; x >= 0; x--)
    {
        sda_out(sel, addr & (1 << x));
        TIMER__Wait_us(SW_I2C_WAIT_TIME);
        i2c_clk_data_out(sel);
//        TIMER__Wait_us(SW_I2C_WAIT_TIME);
    }
}

void i2c_send_ack(uint8_t sel)
{
    sda_out_mode(sel);
    sda_low(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME);
    scl_high(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME << 1);

    sda_low(sel);
    TIMER__Wait_us(SW_I2C_WAIT_TIME << 1);

    scl_low(sel);

    sda_out_mode(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME);
}

/* external functions */
uint8_t SW_I2C_ReadVal_SDA(uint8_t sel)
{
    if(sel == 1)
        return GPIO_ReadInputDataBit(SW_I2C1_SDA_GPIO, SW_I2C1_SDA_PIN);
    else if(sel == 2)
        return GPIO_ReadInputDataBit(SW_I2C2_SDA_GPIO, SW_I2C2_SDA_PIN);
    else if(sel == 3)
        return GPIO_ReadInputDataBit(SW_I2C3_SDA_GPIO, SW_I2C3_SDA_PIN);
    else if(sel == 4)
        return GPIO_ReadInputDataBit(SW_I2C4_SDA_GPIO, SW_I2C4_SDA_PIN);
    else if(sel == 5)
        return GPIO_ReadInputDataBit(SW_I2C5_SDA_GPIO, SW_I2C5_SDA_PIN);
    else if(sel == 6)
        return GPIO_ReadInputDataBit(SW_I2C6_SDA_GPIO, SW_I2C6_SDA_PIN);
    else if(sel == 7)
        return GPIO_ReadInputDataBit(SW_I2C7_SDA_GPIO, SW_I2C7_SDA_PIN);
    else if(sel == 8)
        return GPIO_ReadInputDataBit(SW_I2C8_SDA_GPIO, SW_I2C8_SDA_PIN);
    else if(sel == 9)
        return GPIO_ReadInputDataBit(SW_I2C9_SDA_GPIO, SW_I2C9_SDA_PIN);
    else if(sel == 10)
        return GPIO_ReadInputDataBit(SW_I2C10_SDA_GPIO, SW_I2C10_SDA_PIN);
    return 0;
}

uint8_t SW_I2C_ReadVal_SCL(uint8_t sel)
{
    if(sel == 1)
        return GPIO_ReadInputDataBit(SW_I2C1_SCL_GPIO, SW_I2C1_SCL_PIN);
    else if(sel == 2)
        return GPIO_ReadInputDataBit(SW_I2C2_SCL_GPIO, SW_I2C2_SCL_PIN);
    else if(sel == 3)
        return GPIO_ReadInputDataBit(SW_I2C3_SCL_GPIO, SW_I2C3_SCL_PIN);
    else if(sel == 4)
        return GPIO_ReadInputDataBit(SW_I2C4_SCL_GPIO, SW_I2C4_SCL_PIN);
    else if(sel == 5)
        return GPIO_ReadInputDataBit(SW_I2C5_SCL_GPIO, SW_I2C5_SCL_PIN);
    else if(sel == 6)
        return GPIO_ReadInputDataBit(SW_I2C6_SCL_GPIO, SW_I2C6_SCL_PIN);
    else if(sel == 7)
        return GPIO_ReadInputDataBit(SW_I2C7_SCL_GPIO, SW_I2C7_SCL_PIN);
    else if(sel == 8)
        return GPIO_ReadInputDataBit(SW_I2C8_SCL_GPIO, SW_I2C8_SCL_PIN);
    else if(sel == 9)
        return GPIO_ReadInputDataBit(SW_I2C9_SCL_GPIO, SW_I2C9_SCL_PIN);
    else if(sel == 10)
        return GPIO_ReadInputDataBit(SW_I2C10_SCL_GPIO, SW_I2C10_SCL_PIN);
    return 0;
}

void SW_I2C_Write_Data(uint8_t sel, uint8_t data)
{
    int  x;

    scl_low(sel);

    for (x = 7; x >= 0; x--)
    {
        sda_out(sel, data & (1 << x));
        TIMER__Wait_us(SW_I2C_WAIT_TIME);
        i2c_clk_data_out(sel);
//        TIMER__Wait_us(SW_I2C_WAIT_TIME);
    }
}

uint8_t SW_I2C_Read_Data(uint8_t sel)
{
    int      x;
    uint8_t  readdata = 0;

    sda_in_mode(sel);

    for (x = 8; x--;)
    {
        scl_high(sel);

        readdata <<= 1;
        if (SW_I2C_ReadVal_SDA(sel))
            readdata |= 0x01;

        TIMER__Wait_us(SW_I2C_WAIT_TIME);
        scl_low(sel);

        TIMER__Wait_us(SW_I2C_WAIT_TIME);
    }

    sda_out_mode(sel);
    return readdata;
}

uint8_t SW_I2C_WriteControl_8Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint8_t data)
{
    uint8_t   returnack = TRUE;

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, WRITE_CMD);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    i2c_register_address(sel, regaddr);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    SW_I2C_Write_Data(sel, data);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    i2c_stop_condition(sel);

    return returnack;
}

uint8_t SW_I2C_WriteControl_8Bit_OnlyRegAddr(uint8_t sel, uint8_t IICID, uint8_t regaddr)
{
    uint8_t   returnack = TRUE;

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, WRITE_CMD);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }

    i2c_register_address(sel, regaddr);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }

//    i2c_stop_condition(sel);

    return returnack;
}

uint8_t SW_I2C_WriteControl_16Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint16_t data)
{
    uint8_t   returnack = TRUE;

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, WRITE_CMD);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    i2c_register_address(sel, regaddr);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    SW_I2C_Write_Data(sel, (data >> 8) & 0xFF);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    SW_I2C_Write_Data(sel, data & 0xFF);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    i2c_stop_condition(sel);

    return returnack;
}

uint8_t SW_I2C_ReadControl_8Bit_OnlyRegAddr(uint8_t sel, uint8_t IICID, uint8_t regaddr)
{
    uint8_t   returnack = TRUE;

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, WRITE_CMD);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    i2c_register_address(sel, regaddr);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    i2c_stop_condition(sel);

    return returnack;
}

uint8_t SW_I2C_ReadControl_8Bit_OnlyData(uint8_t sel, uint8_t IICID)
{
    uint8_t  readdata = 0;

    i2c_port_initial(sel);

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, READ_CMD);
    i2c_check_ack(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    readdata = SW_I2C_Read_Data(sel);

    i2c_check_not_ack(sel);

    i2c_stop_condition(sel);

    return readdata;
}

uint16_t SW_I2C_ReadControl_16Bit_OnlyData(uint8_t sel, uint8_t IICID)
{
    uint8_t  readimsi = 0;
    uint16_t  readdata = 0;

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, READ_CMD);
    i2c_check_not_ack(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    readimsi = SW_I2C_Read_Data(sel);
    i2c_check_not_ack_continue(sel);

    readdata = readimsi<<8;

    readimsi = SW_I2C_Read_Data(sel);
    i2c_check_not_ack(sel);


    readdata |= readimsi;

    i2c_stop_condition(sel);

    return readdata;
}

uint8_t SW_I2C_ReadControl_8Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr)
{
    uint8_t  readdata = 0;

    i2c_port_initial(sel);

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, WRITE_CMD);
    i2c_check_ack(sel);

    i2c_register_address(sel, regaddr);
    i2c_check_ack(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, READ_CMD);
    i2c_check_ack(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    readdata = SW_I2C_Read_Data(sel);

    i2c_check_not_ack(sel);

    i2c_stop_condition(sel);

    return readdata;
}

uint16_t SW_I2C_ReadControl_16Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr)
{
    uint16_t  readdata = 0;

    i2c_port_initial(sel);

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, WRITE_CMD);
    i2c_check_ack(sel);

    i2c_register_address(sel, regaddr);
    i2c_check_ack(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, READ_CMD);
    i2c_check_ack(sel);

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    readdata = SW_I2C_Read_Data(sel);
    i2c_send_ack(sel);
    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    readdata = ((readdata << 8) | SW_I2C_Read_Data(sel));

    i2c_check_not_ack(sel);

    i2c_stop_condition(sel);

    return readdata;
}

uint8_t SW_I2C_ReadnControl_8Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint8_t rcnt, uint8_t (*pdata))
{
    uint8_t   returnack = TRUE;
    uint8_t  index;

    i2c_port_initial(sel);

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, WRITE_CMD);
    if (!i2c_check_ack(sel)) { returnack = FALSE; }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);
	
    i2c_register_address(sel, regaddr);
    if (!i2c_check_ack(sel)) { returnack = FALSE; }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, READ_CMD);
    if (!i2c_check_ack(sel)) { returnack = FALSE; }

    for ( index = 0 ; index < rcnt ; index++){
    	TIMER__Wait_us(SW_I2C_WAIT_TIME);
    	pdata[index] = SW_I2C_Read_Data(sel);
    }

    pdata[rcnt-1] = SW_I2C_Read_Data(sel);
	
    i2c_check_not_ack(sel);

    i2c_stop_condition(sel);

    return returnack;
}

uint8_t SW_I2C_Multi_ReadnControl_8Bit(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint8_t rcnt, uint8_t (*pdata))
{
    uint8_t   returnack = TRUE;
    uint8_t  index;

    i2c_port_initial(sel);

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, WRITE_CMD);
    if (!i2c_check_ack(sel)) { returnack = FALSE; }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);
	
    i2c_register_address(sel, regaddr);
    if (!i2c_check_ack(sel)) { returnack = FALSE; }

    TIMER__Wait_us(SW_I2C_WAIT_TIME);

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, READ_CMD);
    if (!i2c_check_ack(sel)) { returnack = FALSE; }

    for ( index = 0 ; index < (rcnt-1) ; index++){
    	TIMER__Wait_us(SW_I2C_WAIT_TIME);
    	pdata[index] = SW_I2C_Read_Data(sel);
	i2c_send_ack(sel);
	//if (!i2c_check_ack(sel)) { returnack = FALSE; }
    }

    pdata[rcnt-1] = SW_I2C_Read_Data(sel);
	
    i2c_check_not_ack(sel);

    i2c_stop_condition(sel);

    return returnack;
}

uint8_t SW_I2C_Check_SlaveAddr(uint8_t sel, uint8_t IICID)
{
    uint8_t   returnack = TRUE;

    i2c_start_condition(sel);

    i2c_slave_address(sel, IICID, WRITE_CMD);
    if (!i2c_check_ack(sel))
    {
        returnack = FALSE;
    }
	
    return returnack;
}

uint8_t SW_I2C_UTIL_WRITE(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint8_t data)
{
	return SW_I2C_WriteControl_8Bit(sel, IICID<<1, regaddr, data);
}

uint8_t SW_I2C_UTIL_Read(uint8_t sel, uint8_t IICID, uint8_t regaddr)
{
	return SW_I2C_ReadControl_8Bit(sel, IICID<<1, regaddr);
}

uint8_t SW_I2C_UTIL_Read_Multi(uint8_t sel, uint8_t IICID, uint8_t regaddr, uint8_t rcnt, uint8_t (*pdata))
{
	return SW_I2C_Multi_ReadnControl_8Bit(sel, IICID<<1, regaddr, rcnt, pdata);
}
반응형

+ Recent posts