talhasevinc / STM32

There are some module libraries,SSD1306,MPL3115A2,MPU6050, GPS , Software I2C,Uart and PWM etc.
10 stars 4 forks source link

Software_I2C Bug #1

Open Chilkings opened 2 years ago

Chilkings commented 2 years ago

In I2C.cpp file,the three GPIO Init struct should be define in class I2C. When you creat more then one class,it will cause some problem in changeSDAState function. And SDAPinInput struct is useless.

#include "I2C.h"

GPIO_InitTypeDef SDAPinInit = {0};
GPIO_InitTypeDef SCLPinInit = {0};
GPIO_InitTypeDef SDAPinInput = {0};

I2C::I2C(GPIO_TypeDef *SDAPort,uint32_t SDAPin,GPIO_TypeDef *SCLPort,uint32_t SCLPin)
    :SDA(SDAPort),SCL(SCLPort),SDAP(SDAPin),SCLP(SCLPin)
rtek1000 commented 1 year ago

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

rtek1000 commented 1 year ago

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