247 lines
5.3 KiB
C
247 lines
5.3 KiB
C
|
#include "drv_i2c.h"
|
||
|
#include "drv_gpio.h"
|
||
|
#include "kit_data.h"
|
||
|
#include "kit_time.h"
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t clk_dly; //单位us
|
||
|
uint8_t scl_io;
|
||
|
uint8_t sda_io;
|
||
|
uint32_t err_cnt;
|
||
|
}I2cItem;
|
||
|
|
||
|
I2cItem i2c_item[kI2cDev_End];
|
||
|
|
||
|
kit_ret_e drv_i2c_init(I2cDev dev, uint32_t freq, uint8_t scl_idx, uint8_t sda_idx)
|
||
|
{
|
||
|
I2cItem *item = &i2c_item[dev];
|
||
|
|
||
|
item->scl_io = scl_idx;
|
||
|
item->sda_io = sda_idx;
|
||
|
|
||
|
item->clk_dly = 1000 / freq;
|
||
|
|
||
|
return kKit_Ret_Ok;
|
||
|
}
|
||
|
|
||
|
void drv_i2c_start(I2cItem *item)
|
||
|
{
|
||
|
|
||
|
drv_gpio_set_pin_status(item->sda_io, kGpioStatus_High);
|
||
|
drv_gpio_set_pin_status(item->scl_io, kGpioStatus_High);
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
drv_gpio_set_pin_status(item->sda_io, kGpioStatus_Low);;
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
drv_gpio_set_pin_status(item->scl_io, kGpioStatus_Low);
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
}
|
||
|
|
||
|
|
||
|
void drv_i2c_stop(I2cItem *item)
|
||
|
{
|
||
|
drv_gpio_set_pin_status(item->sda_io, kGpioStatus_Low);
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
drv_gpio_set_pin_status(item->scl_io, kGpioStatus_High);
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
drv_gpio_set_pin_status(item->sda_io, kGpioStatus_High);
|
||
|
}
|
||
|
|
||
|
|
||
|
kit_ret_e i2c_sync_write_byte(I2cItem *item, uint8_t data)
|
||
|
{
|
||
|
kit_ret_e res = kKit_Ret_Error;
|
||
|
uint32_t i;
|
||
|
|
||
|
for(i = 0; i < 8; i++)
|
||
|
{
|
||
|
if((data & 0x80) == 0)
|
||
|
{
|
||
|
drv_gpio_set_pin_status(item->sda_io, kGpioStatus_Low);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
drv_gpio_set_pin_status(item->sda_io, kGpioStatus_High);
|
||
|
}
|
||
|
kit_time_dly_us(2);
|
||
|
drv_gpio_set_pin_status(item->scl_io, kGpioStatus_High);
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
drv_gpio_set_pin_status(item->scl_io, kGpioStatus_Low);
|
||
|
data <<= 1;
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
}
|
||
|
drv_gpio_set_pin_status(item->sda_io, kGpioStatus_High);
|
||
|
drv_gpio_set_pin_mode(item->sda_io, kGpioMode_Input_Floating);
|
||
|
drv_gpio_set_pin_status(item->scl_io, kGpioStatus_High);
|
||
|
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
if(drv_gpio_get_pin_status(item->sda_io) == kGpioStatus_Low)
|
||
|
{
|
||
|
res = kKit_Ret_Ok;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
item->err_cnt++;
|
||
|
}
|
||
|
|
||
|
drv_gpio_set_pin_status(item->scl_io, kGpioStatus_Low);
|
||
|
drv_gpio_set_pin_mode(item->sda_io, kGpioMode_Output_PP);
|
||
|
drv_gpio_set_pin_status(item->sda_io, kGpioStatus_High);
|
||
|
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
uint8_t i2c_sync_read_byte(I2cItem *item, bool is_ack)
|
||
|
{
|
||
|
uint8_t data = 0;
|
||
|
uint32_t i;
|
||
|
|
||
|
drv_gpio_set_pin_mode(item->sda_io, kGpioMode_Input_Floating);
|
||
|
kit_time_dly_us(1);
|
||
|
for(i = 0; i < 8; i++)
|
||
|
{
|
||
|
data <<= 1;
|
||
|
drv_gpio_set_pin_status(item->scl_io, kGpioStatus_High);
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
if(drv_gpio_get_pin_status(item->sda_io) == kGpioStatus_High)
|
||
|
{
|
||
|
data |= 0x01;
|
||
|
}
|
||
|
drv_gpio_set_pin_status(item->scl_io, kGpioStatus_Low);
|
||
|
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
}
|
||
|
|
||
|
drv_gpio_set_pin_mode(item->sda_io, kGpioMode_Output_PP);
|
||
|
if(is_ack == true)
|
||
|
{
|
||
|
drv_gpio_set_pin_status(item->sda_io, kGpioStatus_Low);;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
drv_gpio_set_pin_status(item->sda_io, kGpioStatus_High);
|
||
|
}
|
||
|
|
||
|
drv_gpio_set_pin_status(item->scl_io, kGpioStatus_High);
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
drv_gpio_set_pin_status(item->scl_io, kGpioStatus_Low);
|
||
|
kit_time_dly_us(item->clk_dly);
|
||
|
drv_gpio_set_pin_status(item->sda_io, kGpioStatus_High);
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
|
||
|
kit_ret_e drv_i2c_sync_write(I2cDev dev, uint8_t dev_addr, uint8_t reg_addr, uint8_t *buf, uint16_t len)
|
||
|
{
|
||
|
uint32_t i;
|
||
|
|
||
|
kit_ret_e res = kKit_Ret_Ok;
|
||
|
I2cItem *item = &i2c_item[dev];
|
||
|
uint8_t snd_buf[10];
|
||
|
|
||
|
drv_i2c_start(item);
|
||
|
|
||
|
snd_buf[0] = dev_addr << 1;
|
||
|
snd_buf[1] = reg_addr;
|
||
|
kit_copy_buf(&snd_buf[2], buf, len);
|
||
|
|
||
|
len += 2;
|
||
|
for(i = 0; i < len; i++)
|
||
|
{
|
||
|
res = i2c_sync_write_byte(item, snd_buf[i]);
|
||
|
if(res != kKit_Ret_Ok)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
drv_i2c_stop(item);
|
||
|
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
kit_ret_e drv_i2c_sync_read(I2cDev dev, uint8_t dev_addr, uint8_t reg_addr, uint8_t *buf, uint16_t len)
|
||
|
{
|
||
|
uint32_t i;
|
||
|
|
||
|
kit_ret_e res = kKit_Ret_TimeOut;
|
||
|
I2cItem *item = &i2c_item[dev];
|
||
|
|
||
|
drv_i2c_start(item);
|
||
|
|
||
|
if((i2c_sync_write_byte(item, dev_addr << 1) == kKit_Ret_Ok)
|
||
|
&& (i2c_sync_write_byte(item, reg_addr) == kKit_Ret_Ok))
|
||
|
{
|
||
|
// drv_i2c_stop(item);
|
||
|
// kit_time_dly_us(2);
|
||
|
drv_i2c_start(item);
|
||
|
if(i2c_sync_write_byte(item, dev_addr << 1 | 0x01) == kKit_Ret_Ok)
|
||
|
{
|
||
|
for(i = 0; i < len; i++)
|
||
|
{
|
||
|
buf[i] = i2c_sync_read_byte(item, (i != (len - 1)));
|
||
|
}
|
||
|
res = kKit_Ret_Ok;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
drv_i2c_stop(item);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
kit_ret_e drv_i2c_sync_write_then_read(I2cDev dev, uint8_t dev_addr, uint8_t *tx_buf, uint16_t tx_len, uint8_t *rx_buf, uint16_t rx_len)
|
||
|
{
|
||
|
uint32_t i;
|
||
|
|
||
|
kit_ret_e res = kKit_Ret_Ok;
|
||
|
I2cItem *item = &i2c_item[dev];
|
||
|
|
||
|
drv_i2c_start(item);
|
||
|
|
||
|
res |= i2c_sync_write_byte(item, dev_addr << 1);
|
||
|
for(i = 0; i < tx_len; i++)
|
||
|
{
|
||
|
res |= i2c_sync_write_byte(item, tx_buf[i]);
|
||
|
}
|
||
|
if(res == kKit_Ret_Ok)
|
||
|
{
|
||
|
drv_i2c_start(item);
|
||
|
|
||
|
res = i2c_sync_write_byte(item, dev_addr << 1 | 0x01);
|
||
|
if(res == kKit_Ret_Ok)
|
||
|
{
|
||
|
for(i = 0; i < rx_len; i++)
|
||
|
{
|
||
|
rx_buf[i] = i2c_sync_read_byte(item, (i != (rx_len - 1)));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
drv_i2c_stop(item);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
kit_ret_e drv_i2c_sync_direct_read(I2cDev dev, uint8_t dev_addr, uint8_t reg_addr, uint8_t *buf, uint16_t len)
|
||
|
{
|
||
|
uint32_t i;
|
||
|
I2cItem *item = &i2c_item[dev];
|
||
|
kit_ret_e res = kKit_Ret_TimeOut;
|
||
|
|
||
|
drv_i2c_start(item);
|
||
|
if(i2c_sync_write_byte(item, dev_addr << 1 | 0x01) == true)
|
||
|
{
|
||
|
for(i = 0; i < len; i++)
|
||
|
{
|
||
|
buf[i] = i2c_sync_read_byte(item, (i != (len - 1)));
|
||
|
}
|
||
|
res = kKit_Ret_Ok;
|
||
|
}
|
||
|
|
||
|
drv_i2c_stop(item);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
|