#include
#include "esp_log.h"
#include "driver/i2c.h"
#include "kth57xx_iic.h"
#include
static const char *TAG = "kth57xx_i2c";
/**
* @brief i2c master initialization
*/
esp_err_t i2c_master_init(void)
{
int i2c_master_port = I2C_MASTER_NUM;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};
i2c_param_config(i2c_master_port, &conf);
return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}
int kth57xx_set_mode(uint8_t u8_cmd, uint8_t axis, uint8_t *p_status)
{
int ret = 0;
uint8_t write_buf[2];
write_buf[0] = u8_cmd|axis;
ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
ret = i2c_master_read_from_device(I2C_MASTER_NUM, KTH57XX_ADDR, p_status, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
return ret;
}
/**
* @brief 开启持续感应模式
* @param 芯片工作状态(status)
* @retval ret 0通信ok
*/
int kth57xx_continuous_sensing(uint8_t *p_status)
{
return kth57xx_set_mode(KTH57XX_CMD_CONTINUOUS_SENSING, 0x06, p_status);//AB
}
/**
* @brief 开启唤醒睡眠模式
* @param 芯片工作状态(status)
* @retval ret 0通信ok
*/
int kth57xx_wakeup_sleep(uint8_t *p_status)
{
return kth57xx_set_mode(KTH57XX_CMD_WAKEUP_SLEEP, 0x06, p_status);//AB
}
/**
* @brief 开启单次测量模式
* @param 芯片工作状态(status)
* @retval ret 0通信ok
*/
int kth57xx_single_conversion(uint8_t *p_status)
{
return kth57xx_set_mode(KTH57XX_CMD_SINGLE_CONVERSION, 0x06, p_status);//AB
}
/**
* @brief 开启空闲模式
* @param 芯片工作状态(status)
* @retval ret 0通信ok
*/
int kth57xx_idle(uint8_t *p_status)
{
return kth57xx_set_mode(KTH57XX_CMD_IDLE, 0x00, p_status);//AB
}
/**
* @brief 芯片重置
* @param 无
* @retval ret 0通信ok
*/
int kth57xx_reset(void)
{
int ret = 0;
uint8_t write_buf[2];
write_buf[0] = KTH57XX_CMD_RESET;
ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
return ret;
}
/**
* @brief 读取芯片测量结果 芯片测量结果放在 DataReadFrame 数组中
* @param axis:ZYXT 设置对哪个测量项进行输出
* p_status :芯片工作状态(status)
* p_read_data : 读数据
* @retval ret 0通信ok
*/
int kth57xx_read_data_frame(uint8_t u8_axis, uint8_t *p_status, uint8_t *p_read_data)
{
int ret = 0;
uint8_t i;
uint8_t write_buf[2];
uint8_t read_buf[9];
uint8_t readLen = 1;//根据axis来计算一共需要读回多少测量数据,存放在counter中
write_buf[0] = KTH57XX_CMD_DATA_READ | u8_axis;
for(i=0;i<4;i++)
{
readLen = readLen + ( u8_axis & 0x01 )*2;
u8_axis = u8_axis >> 1;
}
ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
if(ret != ESP_OK)
{
return ret;
}
ret = i2c_master_read_from_device(I2C_MASTER_NUM, KTH57XX_ADDR, read_buf, readLen, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
*p_status = read_buf[0];
memcpy(p_read_data, &read_buf[1], readLen-1);
return ret;
}
/**
* @brief 读取芯片测量结果 芯片测量结果放在 DataReadFrame 数组中
* @param p_status :芯片工作状态(status)
* u16_p_data_angle : 读角度
* u16_p_data_B : 读磁场强度
* @retval ret 0通信ok
*/
int kth57xx_read_AB(uint8_t *p_status, uint16_t *u16_p_data_angle, uint16_t *u16_p_data_B)
{
int ret = 0;
uint8_t write_buf[2];
uint8_t read_buf[5];
write_buf[0] = KTH57XX_CMD_DATA_READ | 0x06;//0x06AB
ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
if(ret != ESP_OK)
{
return ret;
}
ret = i2c_master_read_from_device(I2C_MASTER_NUM, KTH57XX_ADDR, read_buf, 5, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
*p_status = read_buf[0];
*u16_p_data_angle = read_buf[1];
*u16_p_data_angle = (*u16_p_data_angle)<<8;
*u16_p_data_angle = (*u16_p_data_angle)|read_buf[2];
*u16_p_data_B = read_buf[3];
*u16_p_data_B = (*u16_p_data_B)<<8;
*u16_p_data_B = (*u16_p_data_B)|read_buf[4];
// ESP_LOGI(TAG, "[kth57xx_read_AB]%x,%x,%x,%x,%x\n", read_buf[0], read_buf[1], read_buf[2], read_buf[3], read_buf[4]);
return ret;
}
/**
* @brief 读取寄存器数据
* 寄存器中的值以及芯片工作状态存
* @param u8_register:寄存器
* p_status :芯片工作状态(status)
* u16_p_read_data : 读寄存器数据
* @retval IIC是否通信成功
*/
int kth57xx_read_register(uint8_t u8_register, uint8_t *p_status, uint16_t *u16_p_read_data)
{
int ret = 0;
uint8_t write_buf[2];
uint8_t read_buf[3];
write_buf[0] = KTH57XX_CMD_READ_REGISTER;
write_buf[1] = u8_register << 2; //读取时寄存器要左移两位
ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
if(ret != ESP_OK)
{
return ret;
}
ret = i2c_master_read_from_device(I2C_MASTER_NUM, KTH57XX_ADDR, read_buf, 3, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
*p_status = read_buf[0];
*u16_p_read_data = read_buf[1];
*u16_p_read_data = (*u16_p_read_data)<<8;
*u16_p_read_data = (*u16_p_read_data)|read_buf[2];
return ret;
}
/**
* @brief 向寄存器中写入配置
* @param u16_write_data:写入寄存器的数据
* u8_register :需写入的寄存器
* p_status :芯片工作状态(status)
* @retval ret
*/
int kth57xx_write_register (uint8_t u8_register, uint16_t u16_write_data, uint8_t *p_status)
{
int ret = 0;
uint8_t write_buf[4];
write_buf[0] = KTH57XX_CMD_WRITE_REGISTER;
write_buf[1] = (u16_write_data >> 8) & 0xff;
write_buf[2] = u16_write_data & 0xff;
write_buf[3] = u8_register <<2 ;//寄存器要左移两位
ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
if(ret != ESP_OK)
{
return ret;
}
ret = i2c_master_read_from_device(I2C_MASTER_NUM, KTH57XX_ADDR, p_status, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
return ret;
}
int kth57xx_set_zero(uint16_t u16_zero_angle)
{
uint8_t u8_status = 0;
uint16_t u16_zero_value = 0;
u16_zero_value = 65536*u16_zero_angle/360/2;
return kth57xx_write_register (KTH57XX_REG_ZERO, (-u16_zero_value)&0x7FFF, &u8_status);
}
int kth57xx_get_AB(float *u16_angle, uint16_t *u16_data_B)
{
int ret = 0;
uint8_t u8_status = 0;
uint16_t u16_data_angle;
ret = kth57xx_read_AB(&u8_status, &u16_data_angle, u16_data_B);
*u16_angle = u16_data_angle * 360.0 /65536;//角度
return ret;
}
void kth57xx_iic_init(void)
{
uint8_t u8_status=0;
ESP_ERROR_CHECK(i2c_master_init());
ESP_LOGI(TAG, "I2C initialized successfully");
vTaskDelay( 5/portTICK_PERIOD_MS );
kth57xx_idle(&u8_status);
vTaskDelay( 1/portTICK_PERIOD_MS );
kth57xx_write_register (KTH57XX_REG_RESERVED_1C, 0x1430, &u8_status);
kth57xx_write_register (KTH57XX_REG_MEAS_TIME_SEL, 0x0002, &u8_status);
kth57xx_write_register (KTH57XX_REG_ZERO, 0x0000, &u8_status);
// ESP_ERROR_CHECK(i2c_driver_delete(I2C_MASTER_NUM));
// ESP_LOGI(TAG, "I2C de-initialized successfully");
}