openharmony 使用 i2c 设置寄存器的值,来驱动相机解串器板。
-
I2cMsg的数据结构(//drivers/hdf_core/framework/include/platform/i2c_if.h)
struct I2cMsg {
/** Address of the I2C device */
uint16_t addr;
/** Address of the buffer for storing transferred data */
uint8_t *buf;
/** Length of the transferred data */
uint16_t len;
/**
* Transfer Mode Flag | Description
* ------------| -----------------------
* I2C_FLAG_READ | Read flag
* I2C_FLAG_ADDR_10BIT | 10-bit addressing flag
* I2C_FLAG_READ_NO_ACK | No-ACK read flag
* I2C_FLAG_IGNORE_NO_ACK | Ignoring no-ACK flag
* I2C_FLAG_NO_START | No START condition flag
* I2C_FLAG_STOP | STOP condition flag
*/
uint16_t flags;
};
其中,flags 字段对应枚举类型:
enum I2cFlag {
/** Read flag. The value <b>1</b> indicates the read operation, and <b>0</b> indicates the write operation. */
I2C_FLAG_READ = (0x1 << 0),
/** 10-bit addressing flag. The value <b>1</b> indicates that a 10-bit address is used. */
I2C_FLAG_ADDR_10BIT = (0x1 << 4),
/** Dma flag. The value <b>1</b> indicates that the buffer of this message is DMA safe. */
I2C_FLAG_DMA = (0x1 << 9),
/** Non-ACK read flag. The value <b>1</b> indicates that no ACK signal is sent during the read process. */
I2C_FLAG_READ_NO_ACK = (0x1 << 11),
/** Ignoring no-ACK flag. The value <b>1</b> indicates that the non-ACK signal is ignored. */
I2C_FLAG_IGNORE_NO_ACK = (0x1 << 12),
/**
* No START condition flag. The value <b>1</b> indicates that there is no START condition for the message
* transfer.
*/
I2C_FLAG_NO_START = (0x1 << 14),
/** STOP condition flag. The value <b>1</b> indicates that the current transfer ends with a STOP condition. */
I2C_FLAG_STOP = (0x1 << 15),
};
-
读取 i2c
int my_read_i2c(int argc, char* argv[])
{
uchar busId = 1;
DevHandle handle = NULL;
int32_t ret = 0;
struct I2cMsg msgs[2]; // 消息结构体数组
int16_t msgs_count = 0;
uint8_t wbuff[128] = { 0 };
uint8_t rbuff[128] = { 0 };
// 解析参数......
// 打开i2c控制器
handle = I2cOpen(busId);
if (handle == NULL)
{
HDF_LOGE("%s: I2cOpen failed\n", __func__, busId);
return -1;
}
// 设置msgs数组有效数目
msgs_count = 2;
// 初始化msgs[0],该部分为主设备发送从设备的i2c内容
msgs[0].addr = m_i2c_slave_address;
msgs[0].flags = toI2cFlags(0,
m_i2c_flags_addr_10bit,
m_i2c_flags_read_no_ack,
m_i2c_flags_ignore_no_ack,
m_i2c_flags_no_start,
m_i2c_flags_stop);
msgs[0].len = 1;
wbuff[0] = m_i2c_reg_address; // 本案例的i2c从设备是第1字节是寄存器地址
msgs[0].buf = wbuff; // 初始化msgs[1],该部分为主设备读取从设备发送的i2c内容
msgs[1].addr = m_i2c_slave_address;
msgs[1].flags = toI2cFlags(1,
m_i2c_flags_addr_10bit,
m_i2c_flags_read_no_ack,
m_i2c_flags_ignore_no_ack,
m_i2c_flags_no_start,
m_i2c_flags_stop);
msgs[1].len = m_i2c_read_data_length;
msgs[1].buf = rbuff; // i2c数据传输,传输次数为2次
ret = I2cTransfer(handle, msgs, msgs_count);
if (ret != msgs_count) {
HDF_LOGE("I2cTransfer(read) failed and ret = %d\n", ret);
goto out;
}
printf("I2cTransfer success and read data length = %d\n", strlen((char *)rbuff));
for (uint32_t i = 0; i < strlen((char *)rbuff); i++) {
printf("rbuff[%d] = 0x%x\n", i, rbuff[i]);
}
out:
// 关闭i2c控制器
I2cClose(handle);
return ret;
}
-
写入 I2c
int my_write_i2c(int argc, char* argv[])
{
uchar busId = 1
DevHandle handle = NULL;
int32_t ret = 0;
struct I2cMsg msgs[2]; // 消息结构体数组
int16_t msgs_count = 0;
uint8_t wbuff[128] = { 0 };
uint8_t rbuff[128] = { 0 };
// 解析参数 ......
// 打开i2c控制器
handle = I2cOpen(busId);
if (handle == NULL) {
HDF_LOGE("%s: I2cOpen failed\n", __func__, busId);
return -1;
}
// 写操作
// 设置msgs数组有效数目
msgs_count = 1;
// 初始化msgs[0],该部分为主设备发送从设备的i2c内容
msgs[0].addr = m_i2c_slave_address;
msgs[0].flags = toI2cFlags(0,
m_i2c_flags_addr_10bit,
m_i2c_flags_read_no_ack,
m_i2c_flags_ignore_no_ack,
m_i2c_flags_no_start,
m_i2c_flags_stop);
msgs[0].len = 2;
wbuff[0] = m_i2c_reg_address;
// 本案例的i2c从设备是第1字节是寄存器地址
wbuff[1] = m_i2c_reg_value;
// 本案例的i2c从设备是第2字节是寄存器数值
msgs[0].buf = wbuff;
// i2c数据传输,传输次数为2次
ret = I2cTransfer(handle, msgs, msgs_count);
if (ret != msgs_count) {
HDF_LOGE("I2cTransfer(write) failed and ret = %d\n", ret);
goto out;
}
printf("I2cTransfer success and write reg(%d), data(%d)\n", m_i2c_reg_address,m_i2c_reg_value);
}
out:
// 关闭i2c控制器
I2cClose(handle);
return ret;
}