a10 linux spi设备驱动开发_第1页
a10 linux spi设备驱动开发_第2页
a10 linux spi设备驱动开发_第3页
a10 linux spi设备驱动开发_第4页
a10 linux spi设备驱动开发_第5页
已阅读5页,还剩19页未读 继续免费阅读

付费下载

下载本文档

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

文档简介

SPI设备驱动 Copyright©AllWinnerTechnology.sSPI(SerialPeripheralInterface)总线是一种由Motorola公司开发的串行总线,用于CPU与各种器件进行全双工、同步串行通讯。SPI总线最主要的优点是时钟速度快,范围可从几MHz到几十MHz,且没有系统开销,但它有一SPISPI总线通过四条线完成MCU与各种器件的通讯,这四条线分别是:(SCLK(MOSI数据线(MISO、从机片选线(SS。位),同时将输入引脚(MISO)中接收到的数据逐位移入到移位寄存器(高位。因此,在主机发送完一个字节后,从器件接收到的数据被移入到换。主机的SPI时钟信号(SCLK)使传输同步,SPI总线的结构如图1所图1SPI总 合成4种工作模式,分别是:SPI0模式,SPI1模式,SPI2模式和SPI3SPI0模式和SPI3模式,详见表1SPILeading0001012103111SPICPOL:CPOL定义了时钟空闲状态电平,对传输协议没有重大影响。为1时,表示时钟空闲状态为CPHA:CPHA定义了数据的采样时间。为0时,表示在时钟的第一个跳变沿(上升沿或下降沿)1时,表示在时钟的第二个跳变沿(上升沿2SPI42SPILinuxSPISPILinux系统对SPI设备具有很好的支持,Linux系统下的SPI驱动程序从逻辑上可以分为3个部分:core:SPI控制器驱动SPImaster:针对不同类型的SPI控制器,实现对总线的具体方法SPISPIdriverSPIread,writeioctl343LinuxSPISPI4LinuxSPISPI(SPISPIcore是Linux内核用来和管理SPI的部分,SPIcore提供接口函数,允许一个SPImaster,SPIdriver和SPIdevice初始化时在SPIcoreSPI控制器驱动(SPISPImaster针对不同类型的SPI控制器硬件,实现比较底层的对SPI总线访问的具体方法。SPImaster通过接口函数向SPIcore一个控制器。SPI设备驱动(SPISPIdriver是对应于SPI设备端的驱动程序,通过接口函数向SPIcore。SPIdriverSPISPI一个具体的SPI设备驱动需要实现两个方面的接口,一方面是对SPIcore层的接口,用以挂接SPImaster来实现对SPI总线及SPI设备具体的方法,包括要实现probe,remove等接口函数;另一方面是对用户应用层的接口,提供用户程序SPI设备的接口,包括实现open,release,read,write以及最重要的ioctl等标准文件操作的接口函数。SPIcore层的接口函数的具体功能解释如下:probe:SPIdriver进行设备绑定的回调函数。remove:SPIdriver解除设备绑定的回调函数。struct{structdevicedev;structlist_headlist;s16 /*总线编号,从零开始u16num_chipselect; /**/u16dma_alignment;u16mode_bits;u16flags;#defineSPI_MASTER_HALF_DUPLEX /*can'tdofullduplex*/#defineSPI_MASTER_NO_RXBIT(1) /*can'tdobufferread*/#defineSPI_MASTER_NO_TX /*can'tdobufferwrite*/spinlock_tbus_lock_spinlock;structmutexbus_lock_mutex;boolbus_lock_flag;int*setup)(structspi_device /*根据spi设备更新硬件配置/*添加消息到队列的方法。这个函数不可睡眠,它的职责是安排发生的传送并且调用的回调函数complete()*/int(*transfer)(structspi_device*spi,structspi_message/*cleanupspidev_release函数中被调用,spidev_releasespirelease函数void(*cleanup)(structspi_device}spi_master对应于一个SPI控制器,spi_master过程中会扫描spi_register_board_info的信息,为每一个与本总线编号相同的信息建立一个structspi_transferconstvoid*tx_buf*要写入设备的数据(dma_safe)NULL*/void*rx_buf;/*要的数据缓冲(必须是dma_safe),或者为NULL*/unsignedlen;/*tx和rx的大小(字节数),他们总是相等的*/dma_addr_ttx_dma; /*tx的dma地址*/dma_addr_trx_dma; /*rx的dma地址*//*影响此次传输的片选,指示本次transfer结束是否要重新片选并调setup改变设置unsignedu8bits_per_word;/*0,使用默认值u16delay_usecs; u32speed_hz; structlist_headtransfer_list;spi_transferSPISPI传输过程可能不只包含个spi_transfer,它可能包含多个spi_transfer,这些spi_transfer最终通过spi_messagestructspi_message/*此次消息的传输队列,一个消息可以包含多个传输段*/structlist_headtransfers;structspi_device /*传输的目的设备unsignedis_dma_mapped:1; /*表示是否是DMA传输方式*/void(*complete)(void*context);/*异步调用完成后的回调函数*/void*context; /*回调函数的参数*/unsigned /*此次传输的实际长度intstatus;/*执行的结果,成功被置0,否则是一个负的错误码*/structlist_headqueue;voidspi_message用来原子的执行spi_transfer表示的一串数组传输请求。这个传输队列是原子的,即在这个消息完成之前不会有其它消息占用SPI总线。消息的执行总是按照FIFO的顺序。structspi_devicestructstruct/*对应的控制器指针/*spi通信时钟片选号,用来区分同一控制器上的设备极性 /*时钟相位 /*时钟极性*/#defineSPI_MODE_0(0|0)#defineSPI_MODE_1(0|SPI_CPHA)#defineSPI_MODE_2#defineSPI_MODE_3 /*片选电位为高#define /*先输出低比特#defineSPI_3WIRE /*输入输出共享接口,此时只能做半双工*/#define #defineSPI_READY每个字长的比特数使用到的中断 /*设备名字spi_deviceSPIspi_device来structspi_board_infochar /*设备名称/*私有数据,会被设置到spi_device.dev.tform_data*/constvoid*tform_data;/*spi_device.controller_data*/void*controller_data;int /*设备中断号u32 /*SPI的最大速率u16 /*SPI总线的编号u16 /*与片选有关u8mode; /*设备的一些模式,例如片选的高低,SPI的连接方式*/序号、片选序号、比特率、SPI传输模式等。structspi_driverconststructspi_device_id/*与spidevice匹配成功后调用,对设备和私有数据进行初始化*/ (*probe)(structspi_device*spi);/*解除spi_device和spi_driver的绑定,释放probe申请的资源*/ (*remove)(structspi_device*spi); /*关闭 (*suspend)(structspi_device*spi,pm_message_tmesg); /*挂起*/ (*resume)(structspi_device*spi); /*恢复*/structspi_driver主要提供驱动模型下的绑定方法和电源管理接口,其成员是和spi_device进行匹配的依据。该结构用于绑定在spi_register_board_info中的对应的spi_device。 intspi_register_driver(structspi_driver thedriverto init= init< init spidevicedrivertospisub- staticinlinevoidspi_unregister_driver(structspi_driver thedriverto spidevicedriverfromspisub- staticinlinevoidspi_set_drvdata(structspi_device*spi,void handletospi Setprivatedatatospi staticinlinevoid*spi_get_drvdata(structspi_device handletospi Theresultofgetspidevicedriver Getprivatedatafromspi staticinlineintspi_write(structspi_device*spi,constu8*buf,size_t devicetowhichdatawillbewritten; databuffer; databuffer write= writethebuffer< negativeerror SPIsynchronous staticinlineintspi_read(structspi_device*spi,u8*buf,size_t devicefromwhichdatawillberead; databuffer; databuffer¾read=<readthebuffernegativeerror SPIsynchronous staticinlinessize_tspi_w8r8(structspi_device*spi,u8 devicewithwhichdatawillbe commandtobewrittenbeforedataisread execute> theeightbitnumberreturnedbythe< negativeerror SPIsynchronous8bitwritefollowedby8bit staticinlinessize_tspi_w8r16(structspi_device*spi,u8 devicewithwhichdatawillbe commandtobewrittenbeforedataisread execute> thesixteenbitnumberreturnedbythe< negativeerror SPIsynchronous8bitwritefollowedby16bit intspi_write_then_read(structspi_device*spi,constu8*txbuf,unsignedn_tx,*rxbuf,unsigned spidevicewithwhichdatawillbeexchanged;txbufdatatobewritten(neednotbedma-safe);n_txsizeoftxbuf,inbytes;rxbufbufferintowhichdatawillberead(neednotbedma-safe);n_rxsizeofrxbuf,inbytes execute= < negativeerror SPIsynchronouswritefollowedby staticinlinevoidspi_message_init(structspi_message thepointertosp Initsp staticinlinevoidspi_message_add_tail(structspi_transfer*t,struct thepointertospitransfer; thepointertosp AddspitransfertospSPISPIdemospi_driver_demo.c,文件 lude lude<linux/kernel.h> lude<linux/init.h>{structdemo structxxxx_tform_data /*如果驱动需要设备板级信息*/pdata=&spi->dev.tform_data;if(!pdata)return-/*为demo结构体开辟内存空间demo

温馨提示

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

最新文档

评论

0/150

提交评论