赞
踩
I2C 是串行低速总线,常见传输速度如下:
工程中常见兼容标准模式和快速模式的 I2C 从设备
设备地址 7 位:101000(0x50)写地址 8 位:设备地址左移一位i,末位补 0 :1010000 (0xA0)读地址 8 位:设备地址左移一位,末位补 1: 1010001 (0xA1)同一个 I2C 设备可能具有多个设备地址,通常可通过从设备的管脚配置,以 I2C 接口的 ROM 芯片 AT24C256 为例:
处理器支持多个 I2C 总线,确认 I2C 设备挂载的总线编号:Hi3516DV300 支持 8 路 I2C 总线,编号 0-7
开启内核选项:CONFIG_I2C_CHARDEV(make menuconfig)
使用 i2c_tools 工具包中的 i2c_detect 命令检测某条总线上挂载的所有设备
具体操作(写操作):
具体操作(读操作):
#define SAMPLE_SERVICE_NAME "at24_service"
struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME);
if(serv == NULL){
printf("fail to get service %s \n", SAMPLE_SERVICE_NAME);
return HDF_FAILURE;
}
对应的 hcs 文件:
i2c_host :: host{
hostName = "my_i2c_test";
priority = 100;
device_i2c :: device {
device0 :: deviceNode {
policy = 2;
priority = 100;
preload = 0;
permission = 0664;
moduleName = "at24_drv";
serviceName = "at24_service";
deviceMatchAttr = "at24_driver_attr";
}
}
}
#define I2C_RD_CMD 456
#define I2C_WR_CMD 789
static int write _data (struct HdfIoService *serv, uint16_t addr, uint8_t value)
{
//用户态写操作
struct HdfSBuf *data = HdfSBufObtainDefault Size();
if(data == NULL){
HDF_LOGE("fail to obtain sbuf data");
ret = HDF_DEV_ERR_NO_MEMORY;
goto out;
}
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
HdfSbufWriteUint16(data, addr);
HdfSbufWriteUint8(data, value);
serv->dispatcher->Dispatch(&serv->object, I2C_WR_CMD, data, reply);
HdfSbufReadString(reply);
printf("Get reply is : %s\n", str);
}
用户态程序读操作:
#define I2C_RD_CMD 456
#define I2C_WR_CMD 789
static int write _data (struct HdfIoService *serv, uint16_t addr, uint8_t value)
{
//用户态读操作
struct HdfSBuf *data = HdfSBufObtainDefault Size();
if(data == NULL){
HDF_LOGE("fail to obtain sbuf data");
ret = HDF_DEV_ERR_NO_MEMORY;
goto out;
}
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
HdfSbufWriteUint16(data, addr);
serv->dispatcher->Dispatch(&serv->object,I2C_RD_CMD, data, reply);
HdfSbufReadUint8(reply, pval);
HdfSbufReadString(reply);
printf("Get reply is : data 0x%hhx, str :%s\n", *pval, str);
}
struct HdfDriverEntry g_SensorDriverEntry = {
.moduleVersion = 1,
.moduleName = "at24_drv",
.Bind = HdfSensorDriverBind,
.Init = HdfSensorDriverInit,
.Release = HdfSensorDriverRelease,
}
HDF_INIT(g_SensorDriverEntry);
i2c_host :: host{
hostName = "my_i2c_test";
priority = 100;
device_i2c :: device {
device0 :: deviceNode {
policy = 2;
priority = 100;
preload = 0;
permission = 0664;
moduleName = "at24_drv";
serviceName = "at24_service";
deviceMatchAttr = "at24_driver_attr";
}
}
}
hcs 设备节点中定义了一个设备私有属性:deviceMatchAttr = “at24_driver_attr”;
static int32_t GetAT24ConfigData(const struct DeviceResourceNode *node)
{ struct DeviceResourceIface *parser = NULL;
const struct DeviceResourceNode *at24 = NULL;
parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
at24 = parser->GetChildNode(node, "at24Attr");
parser->GetUint16(at24, "busId", &(tpDevice.busId), 0);
parser->GetUint16(at24, "addr", &(tpDevice.addr), 0);
parser->GetUint16(at24, "regLen", &(tpDevice.regLen), 0);
return HDF_SUCCESS;
}
int32_t HdfSensorDriverInit(struct HdfDeviceObject *deviceObject)
{
if(GetAT24ConfigData(deviceObject->property) != HDF_SUCCESS){
HDF_LOGE("%s: get at24 config fail!", __func__);
return HDF_FAILURE;
}
if(at24_init() != HDF_SUCCESS){
HDF_LOGE("i2c at24 driver init failed!");
return -1;
}
HDF_LOGD("i2c at24 driver init success.");
return 0;
}
设备私有属性(i2c_test_config.hcs)
root {
match_attr = "at24_driver_attr";
at24Attr { //节点名字 at24Attr
busId = 5; //总线编号 5
addr = 0x50; //设备地址 0x50
regLen = 2; //地址宽度 2字节
}
}
全局配置文件(device_info.hcs)
i2c_host :: host{
hostName = "my_i2c_test";
priority = 100;
device_i2c :: device {
device0 :: deviceNode {
policy = 2;
priority = 100;
preload = 0;
permission = 0664;
moduleName = "at24_drv";
serviceName = "at24_service";
deviceMatchAttr = "at24_driver_attr";
}
}
}
static int32_t at24_init(void)
{
tpDevice.i2cHandle = i2cOpen(tpDevice.busId);
return HDF_SUCCESS;
}
功能分类 | 接口名 | 描述 |
---|---|---|
I2C 控制器管理接口 | I2cOpen | 打开 I2C 控制器 |
I2cClose | 关闭 I2C 控制器 | |
i2c 消息传输接口 | I2cTransfer | 自定义传输 |
int32_t HdfSensorDriverDispatch(struct HdfDeviceIoClient *client, int id, struct HdfSBuf *data, struct HdfSBuf *reply)
{
uint16_t addr = 0;
uint8_t value = 0;
if(id == I2C_WR_CMD){
HdfSbufReadUint16(data, &addr);
HdfSbufReadUint8(data, &value);
TpI2cWriteReg(&tpDevice, addr, &value, 1);
HdfSbufWriteString(reply, "write success");
}
else if(id == I2C_RD_CMD){
HdfSbufReadUint16(data, &addr);
TpI2cWriteReg(&tpDevice, addr, &value, 1);
HdfSbufWriteUint8(reply, value);
HdfSbufWriteString(reply, "read success");
}
}
写数据:
读数据:
struct TpI2cDevice{
uint16_t busId;
uint16_t addr;
uint16_t regLen;
DevHandle i2cHandle;
}
struct I2cMsg{
uin16_t addr; //i2c 设备地址
uintt8_t *buf; //缓存区
uint16_t len; //数据传输长度
uint16_t flags; //传输模式 flags,区分读写。
}
static struct TpI2cDevice tpDevice;
static inline int TpI2cReadReg(struct TpI2cDevice *tpDevice, uint16_t regAddr, uint8_t *regData, uint32_t dataLen)
{
return TpI2cReadWrite()tpDevice, regAddr, regData, dataLen, 1);
}
static inline int TpI2cWriteReg(struct TpI2cDevice *tpDevice, uint16_t regAddr, uint8_t *regData, uint32_t dataLen)
{
return TpI2cReadWrite()tpDevice, regAddr, regData, dataLen, 0);
}
static int TpI2cReadWrite(struct TpI2cDevice *tpDevice, uint16_t regAddr, uint8_t *regData, uint32_t dataLen, uint8_t flaag)
{
int index = 0;
unsigned char regBuf[2] = {0};
struct I2cMsg msgs[2] = {0};
if(tpDevice->regLen == 1){
regBuf[index++] = regAddr & 0xFF;
}
else {
regBuf[index++] = (regAddr >> 8 ) & 0xFF;
regBuf[index++] = regAddr & 0xFF;
}
msgs[0].addr = tpDevice->addr;
msgs[0].flags = 0;
msgs[0].len = tpDevice->regLen;
msgs[0].buf = regBuf;
msgs[1].addr = tpDevice->addr;
msgs[1].flags = (flag == 1) ? I2C_FLAG_READ : 0;
msgs[1].len = dataLen;
msgs[1].buf = regData;
if(I2cTransfer(tpDevice->i2cHandle, msgs, 2) != 2)
return HDF_FAILURE;
return HDF_SUCCESS;
}
读操作:
写操作:
其中参数说明:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。