本帖最后由 robe.zhang 于 2021-7-2 23:14 编辑
【ALINX AXU2CGB试用】IIC数据传输方法框架源码分析
这篇文章分析IIC 数据传输方法框架源码,有的人喜欢叫算法,其实就是IIC传输数据的算法/方法。 其实前文分析 cadence 适配器的时候,已经看过 cadence 的 algo 传输方法了,他没有单列出来方法,是和适配器驱动一起的,cadence 适配器的 algo 方法没啥通用性吧 源码单列出来的 algo 方法分为以下三种: 源码位于 drivers\i2c\algos 目录中: 其中I2C_ALGOBIT 类似于gpio模拟 IIC 总线的传输方式,传输一位移位一次,传输一个字节,需要循环8次。 其他驱动通过方法提供的i2c_bit_add_bus 接口,来使用I2C_ALGOBIT 方法: Struct i2c_algo_bit_data 数据结构如下: 看 i2c_bit_algo 方法的具体实现: 先看 bit_xfer 函数:先运行 adap->pre_xfer函数,然后运行i2c_start 函数,再运行readbytes / sendbytes 函数,再运行i2c_stop 函数,再运行adap->post_xfer函数 i2c_start 函数,是发送个起始信号,拉低 sda 引脚,延迟一会,拉低 scl,完成IIC起始动作,和 IIC 协议时序一摸一样
Readbytes 函数:最外层循环,读取几个字节循环几次。内部调用 i2c_inb 和acknak函数
i2c_inb 函数内部,循环 8 次,每次接受一位的数据,把接受的这一位数据左移保存在indata 中,最后返回 indata。这个过程就是单片机中的GPIO模拟IIC时序接受数据
Acknak 函数:是应答的
I2C_ALGOBIT 就是使用 gpio模拟IIC总线传输的方法,这种传输方式使用的还是很广泛的:
随便从里面找出来一个实例看看具体的实现:比如drivers/video/fbdev/nvidia/nv_i2c.c:109: 第94-100行,他就实现了4 个函数,填了三个参数 delay,timeout,data
正好和前面定义的这个结构体一摸一样,pre_xfer,post_xfer 函数是可有可无的,不使用就不用实现
从这个源码中就能看出框架来,核心代码抽象出公共接口部分,留给各个驱动具体实现,其他部分全部搞定。各自驱动只要提供自己的接口,整个驱动就完成了,既简单方便快捷,又避免写重复的公用代码。
I2C_ALGOPCF 主要是为 PCF8584adapters 准备的数据传输方法 pcf_algo 方法实现: pcf_xfer 函数:先调用 xfer_begin函数,调用 i2c_start 函数,调用 pcf_readbytes/ pcf_sendbytes 函数,调用 xfer_end 函数 i2c_start 函数:向一个地址中写数据 pcf_readbytes 函数,向一个地址中读写数据 pcf_sendbytes 函数,从地址中读写数据:
这几个 adapter 用的 pcf 方法: 看 drivers\i2c\busses\i2c-icy.c 文件中的实现: icy_pcf_setpcf / icy_pcf_getpcf 函数::都是读写一个寄存器的数据 对应的寄存器信息在数据结构中: I2C_ALGOPCF 这种方法就是读写寄存器,传输 IIC 数据
I2C_ALGOPCA 方法也是读写寄存器传输数据的,这个方法主要是针对PCA9564 adapters 快速浏览一下:Pca 结构体: Pca 方法: pca_xfer 函数 一层一层追踪,Pca_start 最终调用了 write_byte 函数 看write_byte 函数具体实现 write_byte 函数实现,读写寄存器,完成数据传输 Readbyte 也是读写寄存器完成 等完成 Reset chip函数空,不需要没实现
用的不是很多
三个IIC 数据传输方法框架源码分析完成 以上三种方法,其实就是完成 IIC 通讯时的时序,波形的。没有控制器,直接用 GPIO 模拟,有控制器读写寄存器,控制器完成时序波形。
|