bs_bcu_app/drv/drv_stm32f4xx/drv_i2c.c

247 lines
5.3 KiB
C
Raw Normal View History

2024-11-07 17:24:19 +08:00
#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];
KitResult 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 kKitResult_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);
}
KitResult i2c_sync_write_byte(I2cItem *item, uint8_t data)
{
KitResult res = kKitResult_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);
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 = kKitResult_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);
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);
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);
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;
}
KitResult drv_i2c_sync_write(I2cDev dev, uint8_t dev_addr, uint8_t reg_addr, uint8_t *buf, uint16_t len)
{
uint32_t i;
KitResult res = kKitResult_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 != kKitResult_Ok)
{
break;
}
}
drv_i2c_stop(item);
return res;
}
KitResult drv_i2c_sync_read(I2cDev dev, uint8_t dev_addr, uint8_t reg_addr, uint8_t *buf, uint16_t len)
{
uint32_t i;
KitResult res = kKitResult_TimeOut;
I2cItem *item = &i2c_item[dev];
drv_i2c_start(item);
if((i2c_sync_write_byte(item, dev_addr << 1) == kKitResult_Ok)
&& (i2c_sync_write_byte(item, reg_addr) == kKitResult_Ok))
{
// drv_i2c_stop(item);
// kit_time_dly_us(2);
drv_i2c_start(item);
if(i2c_sync_write_byte(item, dev_addr << 1 | 0x01) == kKitResult_Ok)
{
for(i = 0; i < len; i++)
{
buf[i] = i2c_sync_read_byte(item, (i != (len - 1)));
}
res = kKitResult_Ok;
}
}
drv_i2c_stop(item);
return res;
}
KitResult 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;
KitResult res = kKitResult_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 == kKitResult_Ok)
{
drv_i2c_start(item);
res = i2c_sync_write_byte(item, dev_addr << 1 | 0x01);
if(res == kKitResult_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;
}
KitResult 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];
KitResult res = kKitResult_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 = kKitResult_Ok;
}
drv_i2c_stop(item);
return res;
}