linux内核GPIO模拟I2C实例.doc_第1页
linux内核GPIO模拟I2C实例.doc_第2页
linux内核GPIO模拟I2C实例.doc_第3页
linux内核GPIO模拟I2C实例.doc_第4页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

linux内核GPIO模拟I2C实例2010-10-11 作者:cvip302814 来源:cvip302814的blog前言:在许多情况下,我们并没有足够的I2C总线,本文主在介绍如何利用Linux内核中的i2c-gpio模块,利用2条GPIO线模拟i2c总线,并挂载设备。思路:先通过对i2c-gpio所定义的结构体初始化(包括初始化i2c的2条线,频率,timeout等)并将i2c-gpio模块编译进内核,实现用GPIO_X,GPIO_Y 2条GPIO线注册新的i2c总线。此时这个模块对i2c设备是透明的,及挂在这2条GPIO线的i2c设备可以直接使用Linux内核通用的i2c设备注册,传输和注销等方法。步骤:首先确认在注册i2c-gpio模块前,所要用到的2条GPIO口是没有被系统其它地方所调用的。在每个系统平台启动时,都会打开一系列的设备,他们通常实现在arch/目录下相应的平台子目录中的例如setup.c,devices.c文件中,在这里我们进行i2c总线的注册以及设备的挂载。i2c-gpio定义的结构在include/linux/i2c-gpio.h中:/*structi2c_gpio_platform_data-Platform-dependentdatafori2c-gpio*sda_pin:GPIOpinIDtouseforSDA*scl_pin:GPIOpinIDtouseforSCL*udelay:signaltoggledelay.SCLfrequencyis(500/udelay)kHz*timeout:clockstretchingtimeoutinjiffies.Iftheslavekeeps* SCLlowforlongerthanthis,thetransferwilltimeout.*sda_is_open_drain:SDAisconfiguredasopendrain,i.e.thepin* isntactivelydrivenhighwhensettingtheoutputvaluehigh.* gpio_get_value()mustreturntheactualpinstateevenifthe* pinisconfiguredasanoutput.*scl_is_open_drain:SCLissetupasopendrain.Samerequirements* asforsda_is_open_drainapply.*scl_is_output_only:SCLoutputdriverscannotbeturnedoff.*/structi2c_gpio_platform_dataunsignedint sda_pin;unsignedint scl_pin;int udelay;int timeout;unsignedint sda_is_open_drain:1;unsignedint scl_is_open_drain:1;unsignedint scl_is_output_only:1;其中sda_pin和scl_pin分别是i2c总线的数据线和时钟线,在i2c-gpio中会通过gpio_request函数对这2个口进行申请,udelay和timeout如果不设初值,i2c-gpio中会自动将其设为默认值。if(pdata-udelay)bit_data-udelay=pdata-udelay;elseif(pdata-scl_is_output_only)bit_data-udelay=50; /*10kHz*/elsebit_data-udelay=5; /*100kHz*/if(pdata-timeout)bit_data-timeout=pdata-timeout;elsebit_data-timeout=HZ/10; /*100ms*/初始化这个结构体后再将其装入platform_device结构体,方便注册:staticstructplatform_devicei2c_device=.name =device-name,.id =your-id,.dev=.platform_data =&i2c_data,/i2c_gpio_platform_data,;注册i2c-gpio设备将i2c设备挂入我们注册的总线:platform_device_register(&i2c_device);staticstructi2c_board_infoi2c_device=I2C_BOARD_INFO(name,i2c_device_addr),;i2c_register_board_info(your-id,i2c_device,ARRAY_SIZE(i2c_device);此时我们就可以在i2c设备的驱动程序中通过遍历所在i2c总线,得到其所在的地址i2c_device_addr。在i2c驱动中,需要注册一个i2c_driver的结构体,例如:staticconststructi2c_device_idlis35de_id=lis35de,0,;staticstructi2c_driverst_lis35de_driver=.probe =st_lis35de_probe,.remove =st_lis35de_remove,.suspend =st_lis35de_suspend,.resume =st_lis35de_resume,.id_table =lis35de_id,.driver =.name =lis35de,;staticint_initst_lis35de_init(void)printk(KERN_INFOst_lis35de_initn);returni2c_add_driver(&st_lis35de_driver);在init时用i2c_add_driver(&st_lis35de_driver),此时将会对所在i2c总线进行遍历并得到该设备的适配器等信息,主要目的即是使驱动得到自己的i2c_client,在这个i2c_client中,已经有了该i2c设备的地址等信息,我们在驱动中定义一个新的i2c_client全局变量,把得到的这个i2c_client传给这个全局变量,从而可以继续后面的i2c操作。此时我们就可以使用通用的i2c读写操作了。总结:直接用GPIO口模拟I2C时序和利用内核模块i2c-gpio虚拟i2c总线的区别:1 用GPIO口模拟I2C时序不需要在系统启动时注册I2C总线,只需要在I2C设备驱动中单独实现。用i2c-gpio模块虚拟i2c总线需要在系统启动时注册新的I2C总线,并将i2c设备挂载到新的i2c总线,涉及的范围较广。2 用GPIO口模拟I2C时序,代码操作较繁琐,且不方便挂载多个i2c设备。用i2c-gpio模块可以完全模拟i2c总线,可以挂载多个设备。3 在i2c读写操作时,用GPIO口模拟I2C时序需要每次根据读/写操作发送器件地址1+1/0,然后再发送寄存器地址。用i2c-gpio模块相当于直接在i2c总线上操作,在系统启动挂载i2c设备时已经告诉了i2c总线它的地址,在该设备自己的驱动中,只需要通过i2c_add_driver操作即可以得到其地址等诸多信息,读写操作只需要发送寄存器地址即可。附:i2c一般的读写操作#include/*读操作:*/staticinti2c_RxData(char*rxData,intlength)structi2c_msgmsgs=/*把1个字节的i2c设备寄存器地址告诉总线*/.addr=client-addr,.flags=0,/写操作.len=1,.buf=rxData,/*从总线读取length个字节的数据,存入rxData*/.addr=client-addr,.flags=I2C_M_RD,/I2C_M_RD在i2c.h中被定义为1,读操作.len=length,.buf=rxData,;if(i2

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论