Code Monkey home page Code Monkey logo

Comments (2)

rtek1000 avatar rtek1000 commented on September 26, 2024

If anyone needs multiple ports, I found this example code (I haven't tested it):

(Comment translated from Korean)

[2020. 2. 4. 11:33]
When using STM32F10x series MCU and needing to control more than 2 I2C devices with overlapping slave addresses, software I2C example code of 100kHz to 400kHz clock speed level is shared.

For reference, since it is controlled only with GPIO, stm32f10x_i2c.h / stm32f10x_i2c.c related STM32 library is not required. And the GPIO settings (GPIOC PIN0, GPIOC PIN14, etc.) for each software I2C channel can be arbitrarily set by the 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);
}

Source: https://schkorea.tistory.com/437

Ref.: https://github.com/liyanboy74/soft-i2c

from stm32.

rtek1000 avatar rtek1000 commented on September 26, 2024

I compressed the routines using arrays:
(Compiled without errors on STM32CubeIDE, but not yet tested.)

/*
 * SCHKorea_soft_i2c.c
 *
 *  Created on: 2020. 2. 4. 11:33
 *      Author: SCHKorea
 *
 *  Modified on: May/22/2023
 *      by RTEK1000 (STM32F40x)
 *
 *  [STM32F10x] software I2C example code
 *  https://schkorea.tistory.com/437
 *
 */

#include "SCHKorea_i2c_sw.h"

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

//stm32f10x:
//#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

//stm32f40x: #todo: calc SW_I2C_WAIT_TIME

// 22 x2.333 (from 72MHz for F10x to 168MHz for F40x)
#define  SW_I2C_WAIT_TIME  51	//100Khz(10.0us)

//#define  SW_I2C_WAIT_TIME  26	//87.719khz(11.4us)
//#define  SW_I2C_WAIT_TIME  25	//90.909kHz(11.0us)
//#define  SW_I2C_WAIT_TIME  23	//96.153kHz(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

GPIO_TypeDef *SW_I2C_SCL_GPIO[SW_I2C_PORTS_COUNT] = { 0 };
uint16_t SW_I2C_SCL_PIN[SW_I2C_PORTS_COUNT] = { 0 };

GPIO_TypeDef *SW_I2C_SDA_GPIO[SW_I2C_PORTS_COUNT] = { 0 };
uint16_t SW_I2C_SDA_PIN[SW_I2C_PORTS_COUNT] = { 0 };

static void GPIO_SetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
static void GPIO_ResetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
static GPIO_PinState GPIO_ReadInputDataBit(GPIO_TypeDef *GPIOx,
		uint16_t GPIO_Pin);

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

/* internal static functions */
void SW_I2C_initial(void) {

	uint8_t index = 0;

#ifdef SW_I2C1
	SW_I2C_SCL_GPIO[index] = SW_I2C1_SCL_GPIO;
	SW_I2C_SCL_PIN[index] = SW_I2C1_SCL_PIN;

	SW_I2C_SDA_GPIO[index] = SW_I2C1_SDA_GPIO;
	SW_I2C_SDA_PIN[index] = SW_I2C1_SDA_PIN;
#endif

	index++;

#ifdef SW_I2C2
	SW_I2C_SCL_GPIO[index] = SW_I2C2_SCL_GPIO;
	SW_I2C_SCL_PIN[index] = SW_I2C2_SCL_PIN;

	SW_I2C_SDA_GPIO[index] = SW_I2C2_SDA_GPIO;
	SW_I2C_SDA_PIN[index] = SW_I2C2_SDA_PIN;
#endif

	index++;

#ifdef SW_I2C3
	SW_I2C_SCL_GPIO[index] = SW_I2C3_SCL_GPIO;
	SW_I2C_SCL_PIN[index] = SW_I2C3_SCL_PIN;

	SW_I2C_SDA_GPIO[index] = SW_I2C3_SDA_GPIO;
	SW_I2C_SDA_PIN[index] = SW_I2C3_SDA_PIN;
#endif

	index++;

#ifdef SW_I2C4
	SW_I2C_SCL_GPIO[index] = SW_I2C4_SCL_GPIO;
	SW_I2C_SCL_PIN[index] = SW_I2C4_SCL_PIN;

	SW_I2C_SDA_GPIO[index] = SW_I2C4_SDA_GPIO;
	SW_I2C_SDA_PIN[index] = SW_I2C4_SDA_PIN;
#endif

	__HAL_RCC_GPIOE_CLK_ENABLE(); // For this case all I2C GPIO are GPIOE

	GPIO_InitTypeDef GPIO_InitStruct = { 0 };

	for (uint8_t i = 0; i < SW_I2C_PORTS_COUNT; i++) {
		scl_out_mode(i);
		sda_out_mode(i);
	}
}

static void GPIO_SetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) {
	HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET);
}

static void GPIO_ResetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) {
	HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_RESET);
}

static GPIO_PinState GPIO_ReadInputDataBit(GPIO_TypeDef *GPIOx,
		uint16_t GPIO_Pin) {
	return HAL_GPIO_ReadPin(GPIOx, GPIO_Pin);
}

// SDA High
void sda_high(uint8_t sel) {
	GPIO_SetBits(SW_I2C_SDA_GPIO[sel], SW_I2C_SDA_PIN[sel]);
}

// SDA low
void sda_low(uint8_t sel) {
	GPIO_ResetBits(SW_I2C_SDA_GPIO[sel], SW_I2C_SDA_PIN[sel]);
}

// SCL High
void scl_high(uint8_t sel) {
	GPIO_SetBits(SW_I2C_SCL_GPIO[sel], SW_I2C_SCL_PIN[sel]);
}

// SCL low
void scl_low(uint8_t sel) {
	GPIO_ResetBits(SW_I2C_SCL_GPIO[sel], SW_I2C_SCL_PIN[sel]);
}

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_InitStruct = { 0 };

	GPIO_InitStruct.Pin = SW_I2C_SDA_PIN[sel];
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(SW_I2C_SDA_GPIO[sel], &GPIO_InitStruct);
}

void sda_out_mode(uint8_t sel) {
	GPIO_InitTypeDef GPIO_InitStruct = { 0 };

	GPIO_InitStruct.Pin = SW_I2C_SDA_PIN[sel];
	GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(SW_I2C_SDA_GPIO[sel], &GPIO_InitStruct);
}

void scl_in_mode(uint8_t sel) {
	GPIO_InitTypeDef GPIO_InitStruct = { 0 };

	GPIO_InitStruct.Pin = SW_I2C_SCL_PIN[sel];
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(SW_I2C_SCL_GPIO[sel], &GPIO_InitStruct);
}

void scl_out_mode(uint8_t sel) {
	GPIO_InitTypeDef GPIO_InitStruct = { 0 };

	GPIO_InitStruct.Pin = SW_I2C_SCL_PIN[sel];
	GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(SW_I2C_SCL_GPIO[sel], &GPIO_InitStruct);
}

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) && (sel <= SW_I2C_PORTS_COUNT)) {
		return GPIO_ReadInputDataBit(SW_I2C_SDA_GPIO[sel], SW_I2C_SDA_PIN[sel]);
	}

	return 0;
}

uint8_t SW_I2C_ReadVal_SCL(uint8_t sel) {
	if ((sel >= 1) && (sel <= SW_I2C_PORTS_COUNT)) {
		return GPIO_ReadInputDataBit(SW_I2C_SCL_GPIO[sel], SW_I2C_SCL_PIN[sel]);
	}

	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);
}
/*
 * SCHKorea_soft_i2c.h
 *
 *  Created on: 2020. 2. 4. 11:33
 *      Author: SCHKorea
 *
 *  Modified on: May/22/2023
 *      by RTEK1000
 *
 *  [STM32F10x] software I2C example code
 *  https://schkorea.tistory.com/437
 *
 */

#ifndef INC_SCHKOREA_I2C_SW_H_
#define INC_SCHKOREA_I2C_SW_H_

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

#define u32 uint32_t

#define SW_I2C_PORTS_COUNT	4 // From 1 to 4

/* defines */
#define SW_I2C1_SCL_GPIO  GPIOE
#define SW_I2C1_SCL_PIN   GPIO_PIN_8
#define SW_I2C1_SDA_GPIO  GPIOE
#define SW_I2C1_SDA_PIN   GPIO_PIN_9

#define SW_I2C2_SCL_GPIO  GPIOE
#define SW_I2C2_SCL_PIN   GPIO_PIN_10
#define SW_I2C2_SDA_GPIO  GPIOE
#define SW_I2C2_SDA_PIN   GPIO_PIN_11

#define SW_I2C3_SCL_GPIO  GPIOE
#define SW_I2C3_SCL_PIN   GPIO_PIN_12
#define SW_I2C3_SDA_GPIO  GPIOE
#define SW_I2C3_SDA_PIN   GPIO_PIN_13

#define SW_I2C4_SCL_GPIO  GPIOE
#define SW_I2C4_SCL_PIN   GPIO_PIN_14
#define SW_I2C4_SDA_GPIO  GPIOE
#define SW_I2C4_SDA_PIN   GPIO_PIN_15

#define SW_I2C1		1
#define SW_I2C2		2
#define SW_I2C3		3
#define SW_I2C4		4

/* 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 /* INC_SCHKOREA_I2C_SW_H_ */

from stm32.

Related Issues (2)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.