OMAP3630下的Linux SPI总线驱动分析(1)

2019-07-24 15:25发布

1 SPI概述
      SPI是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口,是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便。
      SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要4根线,事实上3根也可以。也是所有基于SPI的设备共有的,它们是SDI(数据输入),SDO(数据输出),SCLK(时钟),CS(片选)。
      MOSI(SDO):主器件数据输出,从器件数据输入。
      MISO(SDI):主器件数据输入,从器件数据输出。
      SCLK :时钟信号,由主器件产生。
      CS:从器件使能信号,由主器件控制。
      其中CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效,这就允许在同一总线上连接多个SPI设备成为可能。需要注意的是,在具体的应用中,当一条SPI总线上连接有多个设备时,SPI本身的CS有可能被其他的GPIO脚代替,即每个设备的CS脚被连接到处理器端不同的GPIO,通过操作不同的GPIO口来控制具体的需要操作的SPI设备,减少各个SPI设备间的干扰。
      SPI是串行通讯协议,也就是说数据是一位一位从MSB或者LSB开始传输的,这就是SCK时钟线存在的原因,由SCK提供时钟脉冲,MISO、MOSI则基于此脉冲完成数据传输。 SPI支持4-32bits的串行数据传输,支持MSB和LSB,每次数据传输时当从设备的大小端发生变化时需要重新设置SPI Master的大小端。


2 Linux SPI驱动总体架构
      在2.6的linux内核中,SPI的驱动架构可以分为如下三个层次:SPI 核心层、SPI控制器驱动层和SPI设备驱动层。
      Linux 中SPI驱动代码位于drivers/spi目录。
2.1 SPI核心层
      SPI核心层是Linux的SPI核心部分,提供了核心数据结构的定义、SPI控制器驱动和设备驱动的注册、注销管理等API。其为硬件平台无关层,向下屏蔽了物理总线控制器的差异,定义了统一的访问策略和接口;其向上提供了统一的接口,以便SPI设备驱动通过总线控制器进行数据收发。
      Linux中,SPI核心层的代码位于driver/spi/ spi.c。由于该层是平台无关层,本文将不再叙述,有兴趣可以查阅相关资料。
2.2 SPI控制器驱动层
      SPI控制器驱动层,每种处理器平台都有自己的控制器驱动,属于平台移植相关层。它的职责是为系统中每条SPI总线实现相应的读写方法。在物理上,每个SPI控制器可以连接若干个SPI从设备。
      在系统开机时,SPI控制器驱动被首先装载。一个控制器驱动用于支持一条特定的SPI总线的读写。一个控制器驱动可以用数据结构struct spi_master来描述。
      在include/liunx/spi/spi.h文件中,在数据结构struct spi_master定义如下:
  1.     /**
  2.      * struct spi_master - interface to SPI master controller
  3.      * @dev: device interface to this driver
  4.      * @bus_num: board-specific (and often SOC-specific) identifier for a
  5.      *  given SPI controller.
  6.      * @num_chipselect: chipselects are used to distinguish individual
  7.      *  SPI slaves, and are numbered from zero to num_chipselects.
  8.      *  each slave has a chipselect signal, but it's common that not
  9.      *  every chipselect is connected to a slave.
  10.      * @setup: updates the device mode and clocking records used by a
  11.      *  device's SPI controller; protocol code may call this.  This
  12.      *  must fail if an unrecognized or unsupported mode is requested.
  13.      *  It's always safe to call this unless transfers are pending on
  14.      *  the device whose settings are being modified.
  15.      * @transfer: adds a message to the controller's transfer queue.
  16.      * @cleanup: frees controller-specific state
  17.      *
  18.      * Each SPI master controller can communicate with one or more @spi_device
  19.      * children.  These make a small bus, sharing MOSI, MISO and SCK signals
  20.      * but not chip select signals.  Each device may be configured to use a
  21.      * different clock rate, since those shared signals are ignored unless
  22.      * the chip is selected.
  23.      *
  24.      * The driver for an SPI controller manages access to those devices through
  25.      * a queue of spi_message transactions, copying data between CPU memory and
  26.      * an SPI slave device.  For each such message it queues, it calls the
  27.      * message's completion function when the transaction completes.
  28.      */  
  29.     struct spi_master {  
  30.         struct device   dev;  
  31.       
  32.         /* other than negative (== assign one dynamically), bus_num is fully
  33.          * board-specific.  usually that simplifies to being SOC-specific.
  34.          * example:  one SOC has three SPI controllers, numbered 0..2,
  35.          * and one board's schematics might show it using SPI-2.  software
  36.          * would normally use bus_num=2 for that controller.
  37.          */  
  38.         s16         bus_num;  
  39.       
  40.         /* chipselects will be integral to many controllers; some others
  41.          * might use board-specific GPIOs.
  42.          */  
  43.         u16         num_chipselect;  
  44.       
  45.         /* setup mode and clock, etc (spi driver may call many times) */  
  46.         int         (*setup)(struct spi_device *spi);  
  47.       
  48.         /* bidirectional bulk transfers
  49.          *
  50.          * + The transfer() method may not sleep; its main role is
  51.          *   just to add the message to the queue.
  52.          * + For now there's no remove-from-queue operation, or
  53.          *   any other request management
  54.          * + To a given spi_device, message queueing is pure fifo
  55.          *
  56.          * + The master's main job is to process its message queue,
  57.          *   selecting a chip then transferring data
  58.          * + If there are multiple spi_device children, the i/o queue
  59.          *   arbitration algorithm is unspecified (round robin, fifo,
  60.          *   priority, reservations, preemption, etc)
  61.          *
  62.          * + Chipselect stays active during the entire message
  63.          *   (unless modified by spi_transfer.cs_change != 0).
  64.          * + The message transfers use clock and SPI mode parameters
  65.          *   previously established by setup() for this device
  66.          */  
  67.         int         (*transfer)(struct spi_device *spi,  
  68.                             struct spi_message *mesg);  
  69.       
  70.         /* called on release() to free memory provided by spi_master */  
  71.         void            (*cleanup)(struct spi_device *spi);  
  72.     };  
复制代码


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
风的样子
1楼-- · 2019-07-24 16:32
 精彩回答 2  元偷偷看……
风的样子
2楼-- · 2019-07-24 19:45
Driver是为device服务的,spi_driver注册时会扫描SPI bus上的设备,进行驱动和设备的绑定,probe函数用于驱动和设备匹配时被调用。从上面的结构体注释中我们可以知道,SPI的通信是通过消息队列机制,而不是像I2C那样通过与从设备进行对话的方式。
  1.     /**
  2.      * struct spi_device - Master side proxy for an SPI slave device
  3.      * @dev: Driver model representation of the device.
  4.      * @master: SPI controller used with the device.
  5.      * @max_speed_hz: Maximum clock rate to be used with this chip
  6.      *  (on this board); may be changed by the device's driver.
  7.      *  The spi_transfer.speed_hz can override this for each transfer.
  8.      * @chip_select: Chipselect, distinguishing chips handled by @master.
  9.      * @mode: The spi mode defines how data is clocked out and in.
  10.      *  This may be changed by the device's driver.
  11.      *  The "active low" default for chipselect mode can be overridden
  12.      *  (by specifying SPI_CS_HIGH) as can the "MSB first" default for
  13.      *  each word in a transfer (by specifying SPI_LSB_FIRST).
  14.      * @bits_per_word: Data transfers involve one or more words; word sizes
  15.      *  like eight or 12 bits are common.  In-memory wordsizes are
  16.      *  powers of two bytes (e.g. 20 bit samples use 32 bits).
  17.      *  This may be changed by the device's driver, or left at the
  18.      *  default (0) indicating protocol words are eight bit bytes.
  19.      *  The spi_transfer.bits_per_word can override this for each transfer.
  20.      * @irq: Negative, or the number passed to request_irq() to receive
  21.      *  interrupts from this device.
  22.      * @controller_state: Controller's runtime state
  23.      * @controller_data: Board-specific definitions for controller, such as
  24.      *  FIFO initialization parameters; from board_info.controller_data
  25.      * @modalias: Name of the driver to use with this device, or an alias
  26.      *  for that name.  This appears in the sysfs "modalias" attribute
  27.      *  for driver coldplugging, and in uevents used for hotplugging
  28.      *
  29.      * A @spi_device is used to interchange data between an SPI slave
  30.      * (usually a discrete chip) and CPU memory.
  31.      *
  32.      * In @dev, the platform_data is used to hold information about this
  33.      * device that's meaningful to the device's protocol driver, but not
  34.      * to its controller.  One example might be an identifier for a chip
  35.      * variant with slightly different functionality; another might be
  36.      * information about how this particular board wires the chip's pins.
  37.      */  
  38.     struct spi_device {  
  39.         struct device       dev;  
  40.         struct spi_master   *master;  
  41.         u32         max_speed_hz;  
  42.         u8          chip_select;  
  43.         u8          mode;  
  44.     #define SPI_CPHA    0x01            /* clock phase */  
  45.     #define SPI_CPOL    0x02            /* clock polarity */  
  46.     #define SPI_MODE_0  (0|0)           /* (original MicroWire) */  
  47.     #define SPI_MODE_1  (0|SPI_CPHA)  
  48.     #define SPI_MODE_2  (SPI_CPOL|0)  
  49.     #define SPI_MODE_3  (SPI_CPOL|SPI_CPHA)  
  50.     #define SPI_CS_HIGH 0x04            /* chipselect active high? */  
  51.     #define SPI_LSB_FIRST   0x08            /* per-word bits-on-wire */  
  52.     #define SPI_3WIRE   0x10            /* SI/SO signals shared */  
  53.     #define SPI_LOOP    0x20            /* loopback mode */  
  54.         u8          bits_per_word;  
  55.         int         irq;  
  56.         void            *controller_state;  
  57.         void            *controller_data;  
  58.         char            modalias[32];  
  59.       
  60.         /*
  61.          * likely need more hooks for more protocol options affecting how
  62.          * the controller talks to each chip, like:
  63.          *  - memory packing (12 bit samples into low bits, others zeroed)
  64.          *  - priority
  65.          *  - drop chipselect after each word
  66.          *  - chipselect delays
  67.          *  - ...
  68.          */  
  69.     };  
复制代码通常来说spi_device对应着SPI总线上某个特定的slave。


风的样子
3楼-- · 2019-07-24 22:34
3 OMAP3630 SPI控制器
      OMAP3630上SPI是一个主/从的同步串行总线,这边有4个独立的SPI模块(SPI1,SPI2,SPI3,SPI4),各个模块之间的区别在于SPI1支持多达4个SPI设备,SPI2和SPI3支持2个SPI设备,而SPI4只支持1个SPI设备。
      OMAP3630的SPI控制器模块图如下:

图3.1 OMAP3630 SPI控制器模块图

    SPI控制器具有以下特征:
   1.可编程的串行时钟,包括频率,相位,极性。
   2.支持4到32位数据传输
   3.支持4通道或者单通道的从模式
   4.支持主的多通道模式
    4.1全双工/半双工
    4.2只发送/只接收/收发都支持模式
    4.3灵活的I/O端口控制
    4.4每个通道都支持DMA读写
   5.支持多个中断源的中断时间
   6.支持wake-up的电源管理
   7.内置64字节的FIFO
quray1985
4楼-- · 2019-07-24 23:23
资料很详细,谢谢楼主的热心分享
baimiaocun2015
5楼-- · 2019-07-25 04:13
SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要4根线,事实上3根也可以。也是所有基于SPI的设备共有的,它们是SDI(数据输入),SDO(数据输出),SCLK(时钟),CS(片选)。
豆腐块
6楼-- · 2019-07-25 07:26
 精彩回答 2  元偷偷看……

一周热门 更多>