#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; }