6.3物联网RK3399项目开发实录-驱动开发之I2C 使用(wulianjishu666)

物联网开发源码案例集:

链接:https://pan.baidu.com/s/1kfPDpYZpm_G0GBLAup3KTQ?pwd=vgvv

=============================================================

I2C 使用

简介

AIO-3399J 开发板上有 9 个片上 I2C 控制器,各个 I2C 的使用情况如下表:

_images/i2c_list.jpg

本文主要描述如何在该开发板上配置 I2C。

配置 I2C 可分为两大步骤:

  • 定义和注册 I2C 设备

  • 定义和注册 I2C 驱动

下面以配置 GSL3680 为例。

定义和注册 I2C 设备

在注册 I2C 设备时,需要结构体 i2c_client 来描述 I2C 设备。然而在标准 Linux 中,用户只需要提供相应的 I2C 设备信息,Linux 就会根据所提供的信息构造 i2c_client 结构体。

用户所提供的 I2C 设备信息以节点的形式写到 DTS 文件中,如下所示:

kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-edp.dts
&i2c4 {status = "okay";gsl3680: gsl3680@41 {compatible = "gslX680";reg = <0x41>;screen_max_x = <1536>;screen_max_y = <2048>;touch-gpio = <&gpio1 20 IRQ_TYPE_LEVEL_LOW>;reset-gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;};
};

定义和注册 I2C 驱动

定义 I2C 驱动

在定义 I2C 驱动之前,用户首先要定义变量 of_device_id 和 i2c_device_id

of_device_id 用于在驱动中调用 DTS 文件中定义的设备信息,其定义如下所示:

 static struct of_device_id gsl_ts_ids[] = {{.compatible = "gslX680"},{}};

定义变量 i2c_device_id

 static const struct i2c_device_id gsl_ts_id[] = {{GSLX680_I2C_NAME, 0},{}};MODULE_DEVICE_TABLE(i2c, gsl_ts_id);

i2c_driver 如下所示:

 static struct i2c_driver gsl_ts_driver = {.driver = { .name = GSLX680_I2C_NAME,.owner = THIS_MODULE,.of_match_table = of_match_ptr(gsl_ts_ids),},#ifndef CONFIG_HAS_EARLYSUSPEND//.suspend  = gsl_ts_suspend,//.resume   = gsl_ts_resume,#endif.probe      = gsl_ts_probe,.remove     = gsl_ts_remove,.id_table   = gsl_ts_id,};

注:变量 id_table 指示该驱动所支持的设备。

注册 I2C 驱动

使用 i2c_add_driver 函数注册 I2C 驱动。

i2c_add_driver(&gsl_ts_driver);

在调用 i2c_add_driver 注册 I2C 驱动时,会遍历 I2C 设备,如果该驱动支持所遍历到的设备,则会调用该驱动的 probe 函数。

通过 I2C 收发数据

在注册好 I2C 驱动后,即可进行 I2C 通讯。

  • 向从机发送信息:

 int i2c_master_send(const struct i2c_client *client, const char *buf, int count){int ret;struct i2c_adapter *adap = client->adapter;struct i2c_msg msg;msg.addr = client->addr;msg.flags = client->flags & I2C_M_TEN;msg.len = count;msg.buf = (char *)buf;ret = i2c_transfer(adap, &msg, 1);/** If everything went ok (i.e. 1 msg transmitted), return #bytes* transmitted, else error code.*/return (ret == 1) ? count : ret;}
  • 向从机读取信息:

 int i2c_master_recv(const struct i2c_client *client, char *buf, int count){struct i2c_adapter *adap = client->adapter;struct i2c_msg msg;int ret;msg.addr = client->addr;msg.flags = client->flags & I2C_M_TEN;msg.flags |= I2C_M_RD;msg.len = count;msg.buf = buf;ret = i2c_transfer(adap, &msg, 1);/** If everything went ok (i.e. 1 msg received), return #bytes received,* else error code.*/return (ret == 1) ? count : ret;}EXPORT_SYMBOL(i2c_master_recv);

FAQs

Q1: 通信失败,出现这种 log: “timeout, ipd: 0x00, state: 1” 该如何调试?

A1: 请检查硬件上拉是否给电。

Q2: 调用 i2c_transfer 返回值为 -6?

A2: 返回值为 -6 表示为 NACK 错误,即对方设备无应答响应,这种情况一般为外设的问题,常见的有以下几种情况:

  • I2C 地址错误,解决方法是测量 I2C 波形,确认是否 I2C 设备地址错误;

  • I2C slave 设备不处于正常工作状态,比如未给电,错误的上电时序等;

  • 时序不符合 I2C slave 设备所要求也会产生 Nack 信号。

Q3: 当外设对于读时序要求中间是 stop 信号不是 repeat start 信号的时候,该如何处理?

A3: 这时需要调用两次 i2c_transfer, I2C read 拆分成两次,修改如下:

static int i2c_read_bytes(struct i2c_client *client, u8 cmd, u8 *data, u8 data_len) {struct i2c_msg msgs[2];int ret;u8 *buffer;buffer = kzalloc(data_len, GFP_KERNEL);if (!buffer)return -ENOMEM;;msgs[0].addr = client->addr;msgs[0].flags = client->flags;msgs[0].len = 1;msgs[0].buf = &cmd;ret = i2c_transfer(client->adapter, msgs, 1);if (ret < 0) {dev_err(&client->adapter->dev, "i2c read failed\n");kfree(buffer);return ret;}msgs[1].addr = client->addr;msgs[1].flags = client->flags | I2C_M_RD;msgs[1].len = data_len;msgs[1].buf = buffer;ret = i2c_transfer(client->adapter, &msgs[1], 1);if (ret < 0)dev_err(&client->adapter->dev, "i2c read failed\n");elsememcpy(data, buffer, data_len);kfree(buffer);return ret;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/578687.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu20.04LTS+uhd3.15+gnuradio3.8.1源码编译及安装

文章目录 前言一、卸载本地 gnuradio二、安装 UHD 驱动三、编译及安装 gnuradio四、验证 前言 本地 Ubuntu 环境的 gnuradio 是按照官方指导使用 ppa 的方式安装 uhd 和 gnuradio 的&#xff0c;也是最方便的方法&#xff0c;但是存在着一个问题&#xff0c;就是我无法修改底层…

docker环境配置过程中的常见问题

1、pull镜像问题 docker pull jenkins/jenkins:lts Using default tag: latest Trying to pull repository docker.io/library/centos ... Get https://registry-1.docker.io/v2/library/centos/manifests/latest: Get https://auth.docker.io/token?scoperepository%3Alibr…

软考101-上午题-【信息安全】-网络安全

一、网络安全 1-1、安全协议 SSL(Secure Socket Layer&#xff0c;安全套接层)是 Netscape 于 1994年开发的传输层安全协议&#xff0c;用于实现 Web 安全通信。1996 年发布的 SSL3.0 协议草案已经成为一个事实上的Web 安全标准。 端口号是43。 SSL HTTP HTTPS TLS(Transpo…

vlan间单臂路由

【项目实践4】 --vlan间单臂路由 一、实验背景 实验的目的是在一个有限的网络环境中实现VLAN间的通信。网络环境包括两个交换机和一个路由器&#xff0c;交换机之间通过Trunk链路相连&#xff0c;路由器则连接到这两个交换机的Trunk端口上。 二、案例分析 在网络工程中&#…

Springboot+MybatisPlus+EasyExcel实现文件导入数据

记录一下写Excel文件导入数据所经历的问题。 springboot提供的文件处理MultipartFile有关方法&#xff0c;我没有具体看文档&#xff0c;但目测比较复杂&#xff0c; 遂了解学习了一下别的文件上传方法&#xff0c;本文第1节记录的是springboot原始的导入文件方法写法&#xf…

【Linux】体验一款开源的Linux服务器运维管理工具

今天为大家介绍一款开源的 Linux 服务器运维管理工具 - 1panel。 一、安装 根据官方那个提供的在线文档&#xff0c;这款工具的安装需要执行在线安装&#xff0c; # Redhat / CentOScurl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start…

科普:从神经网络到 Hugging Face——神经网络和深度学习简史

活中没有什么可怕的东西&#xff0c;只有需要理解的东西。—— 居里夫人 深度信念网络 2006年&#xff0c;加拿大多伦多大学教授杰弗里辛顿在研究如何训练多层神经网络&#xff0c;他已经在神经网络领域默默耕耘了三十多年&#xff0c;尽管在这个领域他算得上是泰斗级的人物&…

unity3d for web

时光噶然 一晃好多年过去了&#xff08;干了5年的u3d游戏&#xff09;&#xff0c;记得最后一次使用的版本好像是 unity 2017。 那个是 unity3d for webgl 还需要装个插件。用起来很蛋疼。 最近做一个小项目 在选择是用 Layabox 还是 cocosCreate 的时候 我想起了老战友 Uni…

阿里云魔搭发起“ModelScope-Sora开源计划”,将为中国类Sora模型开发提供一站式工具链

在2024年3月23日的全球开发者先锋大会上&#xff0c;阿里云的魔搭社区宣布了一个新计划&#xff1a;“ModelScope-Sora开源计划”。这个计划旨在通过开源方式&#xff0c;帮助中国在Sora模型类型上做出更多创新。这个计划提供了一整套工具&#xff0c;包括处理数据的工具、多模…

JUC:synchronized优化——锁的升级过程(偏向锁->轻量级锁->重量级锁)以及内部实现原理

文章目录 锁的类型轻量级锁重量级锁自旋优化偏向锁偏向锁的细节偏向锁的撤销批量重偏向批量撤销锁消除 锁的类型 重量级锁、轻量级锁、偏向锁。 加锁过程&#xff1a;偏向->轻量级->重量级 轻量级锁 轻量级锁的使用场景&#xff1a;如果一个对象虽然有多线程要加锁&am…

数据结构与算法(2)顺序表的初始化、插入、打印、删除、查找元素——C语言版

目录 1.前言 2.头文件的定义 3.菜单栏的设置 4.顺序表的初始化 5.添加元素 6.打印元素 7.查找元素 8.删除元素 9.插入元素 10.主函数 11.完整的代码实现 1.前言 数据结构包括三个方面 逻辑结构存储结构运算 而线性表有两种典型的存储结构 顺序存储结构链式存储结构 具体关系可…

提取gdip-yolo与ia-seg中的图像自适应模块进行图像去雾与亮度增强

gdip-yolo与ia-seg都是一种将图像自适应模块插入模型前面,从而提升模型在特定数据下检测能力的网络结构。gdip-yolo提出了gdip模块,可以应用到大雾数据与低亮度数据(夜晚环境),然后用于目标检测训练;ia-seg将ia-yolo中的代码修改了一下修车了ipam模块,应用到低亮度数据(…