Open Chilkings opened 2 years 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.
#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 */
#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
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_ */
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.